From 30fa1c08df88b39b760a54624c8af6be798d17f9 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 11 Sep 2012 09:44:43 +0000 Subject: [PATCH 001/447] Initial version git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@1 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 359 +++++++ connectors/vmware/centreon_esxd | 1238 ++++++++++++++++++++++ connectors/vmware/centreon_esxd-conf.pm | 11 + connectors/vmware/centreon_esxd-init | 113 ++ 4 files changed, 1721 insertions(+) create mode 100644 connectors/vmware/centreon_esx_client.pl create mode 100644 connectors/vmware/centreon_esxd create mode 100644 connectors/vmware/centreon_esxd-conf.pm create mode 100644 connectors/vmware/centreon_esxd-init diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl new file mode 100644 index 000000000..727f7a95f --- /dev/null +++ b/connectors/vmware/centreon_esx_client.pl @@ -0,0 +1,359 @@ +#!/usr/bin/perl -w + +use strict; +no strict "refs"; +use IO::Socket; +use Getopt::Long; + +my $PROGNAME = $0; +my $VERSION = "1.0"; +my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); +my $socket; + +sub print_help(); +sub print_usage(); +sub print_revision($$); + +my %OPTION = ( + "help" => undef, "version" => undef, + "esxd-host" => undef, "esxd-port" => 5700, + "usage" => undef, + "esx-host" => undef, + "datastore" => undef, + "nic" => undef, + "warning" => undef, + "critical" => undef +); + +Getopt::Long::Configure('bundling'); +GetOptions( + "h|help" => \$OPTION{'help'}, + "V|version" => \$OPTION{'version'}, + "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, + "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, + + "u|usage=s" => \$OPTION{'usage'}, + "e|esx-host=s" => \$OPTION{'esx-host'}, + + "datastore=s" => \$OPTION{'datastore'}, + "nic=s" => \$OPTION{'nic'}, + + "w|warning=i" => \$OPTION{'warning'}, + "c|critical=i" => \$OPTION{'critical'}, +); + +if (defined($OPTION{'version'})) { + print_revision($PROGNAME, $VERSION); + exit $ERRORS{'OK'}; +} + +if (defined($OPTION{'help'})) { + print_help(); + exit $ERRORS{'OK'}; +} + +############# +# Functions # +############# + +sub print_usage () { + print "Usage: "; + print $PROGNAME."\n"; + print " -V (--version) Plugin version\n"; + print " -h (--help) usage help\n"; + print " -H centreon-esxd Host (required)\n"; + print " -P centreon-esxd Port (default 5700)\n"; + print " -u (--usage) What to check. The list and args (required)\n"; + print "\n"; + print "'healthhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'maintenancehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'statushost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'datastores':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'cpuhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'nethost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " --nic Physical nic name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'memhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'swaphost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; + print "'listhost':\n"; + print " None\n"; + print "\n"; + print "'listdatastore':\n"; + print " None\n"; + print "\n"; + print "'listnichost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; +} + +sub print_help () { + print "##############################################\n"; + print "# Copyright (c) 2005-2012 Centreon #\n"; + print "# Bugs to http://redmine.merethis.net/ #\n"; + print "##############################################\n"; + print "\n"; + print_usage(); + print "\n"; +} + +sub print_revision($$) { + my $commandName = shift; + my $pluginRevision = shift; + print "$commandName v$pluginRevision (centreon-esxd)\n"; +} + +sub myconnect { + if (!($socket = IO::Socket::INET->new( Proto => "tcp", + PeerAddr => $OPTION{'esxd-host'}, + PeerPort => $OPTION{'esxd-port'}))) { + print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; + exit $ERRORS{'UNKNOWN'}; + } + $socket->autoflush(1); +} + +################# +# Func Usage +################# + +sub maintenancehost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub maintenancehost_get_str { + return "maintenancehost|" . $OPTION{'esx-host'}; +} + +sub statushost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub statushost_get_str { + return "statushost|" . $OPTION{'esx-host'}; +} + +sub healthhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub healthhost_get_str { + return "healthhost|" . $OPTION{'esx-host'}; +} + +sub datastores_check_arg { + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub datastores_get_str { + return "datastores|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub cpuhost_check_arg { + + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub cpuhost_get_str { + return "cpuhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub memhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub memhost_get_str { + return "memhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub swaphost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 0.8; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 1; + } + return 0; +} + +sub swaphost_get_str { + return "swaphost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub nethost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'nic'})) { + print "Option --nic is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub nethost_get_str { + return "nethost|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub listhost_check_arg { + return 0; +} + +sub listhost_get_str { + return "listhost"; +} + +sub listdatastore_check_arg { + return 0; +} + +sub listdatastore_get_str { + return "listdatastore"; +} + +sub listnichost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub listnichost_get_str { + return "listnichost|" . $OPTION{'esx-host'}; +} + +################# +################# + +if (!defined($OPTION{'esxd-host'})) { + print "Option -H (--esxd-host) is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} + +if (!defined($OPTION{'usage'})) { + print "Option -u (--usage) is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} +if ($OPTION{'usage'} !~ /^(healthhost|datastores|maintenancehost|statushost|cpuhost|nethost|memhost|swaphost|listhost|listdatastore|listnichost)$/) { + print "Usage value is unknown\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} + +my $func_check_arg = $OPTION{'usage'} . "_check_arg"; +my $func_get_str = $OPTION{'usage'} . "_get_str"; +&$func_check_arg(); +my $str_send = &$func_get_str(); +myconnect(); +print $socket "$str_send\n"; +my $return = <$socket>; +close $socket; + +chomp $return; +$return =~ /^(-?[0-9]*?)\|/; +my $status_return = $1; +$return =~ s/^(-?[0-9]*?)\|//; +print $return . "\n"; + +if ($status_return == -1) { + $status_return = 3; +} +exit $status_return; + +#print $remote "healthhost|srvi-esx-dev-1.merethis.net\n"; +#print $remote "datastores|LUN-VMFS-QGARNIER|80|90\n"; +#print $remote "maintenancehost|srvi-esx-dev-1.merethis.net\n"; +#print $remote "statushost|srvi-esx-dev-1.merethis.net\n"; +#print $remote "cpuhost|srvi-esx-dev-1.merethis.net|60\n"; +#print $remote "nethost|srvi-esx-dev-1.merethis.net|vmnic1|60\n"; +#print $remote "memhost|srvi-esx-dev-1.merethis.net|80\n"; +#print $remote "swaphost|srvi-esx-dev-1.merethis.net|80\n"; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd new file mode 100644 index 000000000..c3882d8b4 --- /dev/null +++ b/connectors/vmware/centreon_esxd @@ -0,0 +1,1238 @@ +#!/usr/bin/perl -w + +BEGIN { + $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; +} + +use strict; +use VMware::VIRuntime; +use VMware::VILib; +use IO::Socket; +use Net::hostent; # for OOish version of gethostbyaddr +use threads; +use Thread::Queue; +use POSIX ":sys_wait_h"; +use Data::Dumper; +use Time::HiRes; + +use vars qw($port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION $LOG); + +require '/etc/centreon/centreon_esxd.pm'; + +our $session_id; +our $data_queue; +our $response_queue; +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 %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}, + "datastores" => {'arg' => \&datastores_check_args, 'compute' => \&datastores_compute_args, 'exec' => \&datastores_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}, + "memhost" => {'arg' => \&memhost_check_args, 'compute' => \&memhost_compute_args, 'exec' => \&memhost_do}, + "swaphost" => {'arg' => \&swaphost_check_args, 'compute' => \&swaphost_compute_args, 'exec' => \&swaphost_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} + ); + +sub writeLogFile($){ + 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, $_[0]; + close LOG; +} + +sub connect_vsphere { + writeLogFile("Vsphere connection in progress\n"); + eval { + $SIG{ALRM} = sub { die('TIMEOUT'); }; + alarm($TIMEOUT_VSPHERE); + Vim::login(service_url=> $service_url, user_name => $username, password => $password); + alarm(0); + }; + if($@) { + writeLogFile("No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/); + writeLogFile("You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/); + writeLogFile("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 $results; + + eval { + $results = Vim::get_views(mo_ref_array => $_[0], properties => $_[1]); + }; + if ($@) { + writeLogFile("$@"); + my $lerror = $@; + $lerror =~ s/\n/ /g; + print "-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("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 (@t) = gmtime(time() - $interval); + my $start = sprintf("%04d-%02d-%02dT%02d:%02d:00Z", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1]); + my $perf_query_spec = PerfQuerySpec->new(entity => $view, + metricId => @perf_metric_ids, + format => 'normal', + intervalId => $interval, + startTime => $start + ); + #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($@); + return undef; + } + return \%results; +} + +sub cache_perf_counters { + eval { + $perfmanager_view = Vim::get_view(mo_ref => Vim::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; + } + } + }; + if ($@) { + writeLogFile($@); + return 1; + } + return 0; +} + +sub get_entities_host { + my ($view_type, $filters, $properties) = @_; + my $entity_views; + + eval { + $entity_views = Vim::find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + }; + if ($@ =~ /decryption failed or bad record mac/) { + writeLogFile("$@"); + eval { + $entity_views = Vim::find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + }; + if ($@) { + my $lerror = $@; + $lerror =~ s/\n/ /g; + print "-1|Error: " . $lerror . "\n"; + return undef; + } + } elsif ($@) { + writeLogFile("$@"); + my $lerror = $@; + $lerror =~ s/\n/ /g; + print "-1|Error: " . $lerror . "\n"; + return undef; + } + if (!@$entity_views) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Host 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; +} + +############## +# Health Function +############## + +sub healthhost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub healthhost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub healthhost_do { + my ($lhost) = @_; + + my %filters = ('name' => $lhost); + my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output_critical = ''; + my $output_critical_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output = ''; + my $output_append = ''; + my $OKCount = 0; + my $CAlertCount = 0; + my $WAlertCount = 0; + foreach my $entity_view (@$result) { + my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo'}; + my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; + if (!defined($cpuStatusInfo)) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + output_add(\$output_critical, \$output_critical_append, ", ", + "API error - unable to get cpuStatusInfo"); + } + if (!defined($numericSensorInfo)) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + output_add(\$output_critical, \$output_critical_append, ", ", + "API error - unable to get numericSensorInfo"); + } + + # CPU + foreach (@$cpuStatusInfo) { + if ($_->status->key =~ /^red$/i) { + output_add(\$output_critical, \$output_critical_append, ", ", + $_->name . ": " . $_->status->summary); + $status |= $MYERRORS_MASK{'CRITICAL'}; + $CAlertCount++; + } elsif ($_->status->key =~ /^yellow$/i) { + output_add(\$output_warning, \$output_warning_append, ", ", + $_->name . ": " . $_->status->summary); + $status |= $MYERRORS_MASK{'WARNING'}; + $WAlertCount++; + } else { + $OKCount++; + } + } + # Sensor + foreach (@$numericSensorInfo) { + if ($_->healthState->key =~ /^red$/i) { + output_add(\$output_critical, \$output_critical_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status |= $MYERRORS_MASK{'CRITICAL'}; + $CAlertCount++; + } elsif ($_->healthState->key =~ /^yellow$/i) { + output_add(\$output_warning, \$output_warning_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status |= $MYERRORS_MASK{'WARNING'}; + $WAlertCount++; + } else { + $OKCount++; + } + } + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - $CAlertCount health issue(s) found: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - $WAlertCount health issue(s) found: $output_warning"; + } + if ($status == 0) { + $output = "All $OKCount health checks are green"; + } + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# Datastores Function +############ + +sub datastores_check_args { + my ($ds, $warn, $crit) = @_; + if (!defined($ds) || $ds eq "") { + writeLogFile("ARGS error: need datastore name\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub datastores_compute_args { + my $ds = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($ds, $warn, $crit); +} + +sub datastores_do { + my ($ds, $warn, $crit) = @_; + my %filters = (); + my @properties = ('datastore'); + + my $result = get_entities_host('Datacenter', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @ds_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->datastore) { + @ds_array = (@ds_array, @{$entity_view->datastore}); + } + } + + @properties = ('summary'); + $result = get_views(\@ds_array, \@properties); + if (!defined($result)) { + return ; + } + + my $ds_find; + foreach my $datastore (@$result) { + if ($datastore->summary->accessible && $datastore->summary->name eq $ds) { + $ds_find = $datastore; + last; + } + } + + my $output = ''; + my $status = 0; # OK + if (defined($ds_find)) { + my $dsName = $ds_find->summary->name; + my $capacity = $ds_find->summary->capacity; + my $free = $ds_find->summary->freeSpace; + my $pct = ($capacity - $free) / $capacity * 100; + + my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; + my $sizeD = $capacity / 1024 / 1024 / 1024; + + $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; + if ($pct >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($pct > $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + } else { + $output = "Datastore '$ds' not found or summary not accessible."; + $status |= $MYERRORS_MASK{'UNKNOWN'}; + } + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# Maintenance Func +############ + +sub maintenancehost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub maintenancehost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub maintenancehost_do { + my ($lhost) = @_; + my %filters = ('name' => $lhost); + my @properties = ('runtime.inMaintenanceMode'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + foreach my $entity_view (@$result) { + if ($entity_view->{'runtime.inMaintenanceMode'} ne "false") { + $status |= $MYERRORS_MASK{'CRITICAL'}; + $output = "Server $lhost is on maintenance mode."; + } else { + $output = "Server $lhost is not on maintenance mode."; + } + } + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# Status Func +############ + +sub statushost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub statushost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub statushost_do { + my ($lhost) = @_; + my %filters = ('name' => $lhost); + my @properties = ('summary.overallStatus'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + my %overallStatus = ( + 'gray' => 'status is unknown', + 'green' => 'is OK', + 'red' => 'has a problem', + 'yellow' => 'might have a problem', + ); + my %overallStatusReturn = ( + 'gray' => 'UNKNOWN', + 'green' => 'OK', + 'red' => 'CRITICAL', + 'yellow' => 'WARNING' + ); + + foreach my $entity_view (@$result) { + my $status = $entity_view->{'summary.overallStatus'}->val; + + if (defined($status) && $overallStatus{$status}) { + $output = "The Server '$lhost' " . $overallStatus{$status}; + if ($MYERRORS_MASK{$overallStatusReturn{$status}} != 0) { + $status |= $MYERRORS_MASK{$overallStatusReturn{$status}}; + } + } else { + $output = "Can't interpret data..."; + $status |= $MYERRORS_MASK{'UNKNOWN'}; + } + } + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# CPUHost Func +############ + +sub cpuhost_check_args { + my ($host, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub cpuhost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($lhost, $warn, $crit); +} + +sub cpuhost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('hardware.cpuInfo.numCpuThreads'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @instances = ('*'); + foreach my $index (0..($$result[0]->{'hardware.cpuInfo.numCpuThreads'} - 1)) { + push @instances, $index; + } + + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'cpu.usage.average', 'instances' => \@instances}], + $perfcounter_speriod); + + my $status = 0; # OK + my $output = ''; + my $total_cpu_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + + if ($total_cpu_average >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($total_cpu_average >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Total Average CPU usage '$total_cpu_average%' on last " . ($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100"; + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %$values) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "") { + $output .= " cpu$instance=" . simplify_number(convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; + } + } + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# NetHost Func +############ + +sub nethost_check_args { + my ($host, $pnic, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + if (!defined($pnic) || $pnic eq "") { + writeLogFile("ARGS error: need physical nic name\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub nethost_compute_args { + my $lhost = $_[0]; + my $pnic = $_[1]; + my $warn = (defined($_[2]) ? $_[2] : 80); + my $crit = (defined($_[3]) ? $_[3] : 90); + return ($lhost, $pnic, $warn, $crit); +} + +sub nethost_do { + my ($lhost, $pnic, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('config.network.pnic'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + my %pnic_def = (); + foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($_->linkSpeed)) { + $pnic_def{$_->device} = $_->linkSpeed->speedMb; + } + } + + if (!defined($pnic_def{$pnic})) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Link '$pnic' not exist or down.\n"; + return ; + } + + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'net.received.average', 'instances' => [$pnic]}, + {'label' => 'net.transmitted.average', 'instances' => [$pnic]}], + $perfcounter_speriod); + + my $traffic_in = simplify_number(convert_number($values->{$perfcounter_cache{'net.received.average'}->{'key'} . ":" . $pnic}[0])); + my $traffic_out = simplify_number(convert_number($values->{$perfcounter_cache{'net.transmitted.average'}->{'key'} . ":" . $pnic}[0])); + my $status = 0; # OK + my $output = ''; + + if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Traffic In : " . simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %), Out : " . simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %)"; + $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# MemHost Func +############ + +sub memhost_check_args { + my ($host, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub memhost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($lhost, $warn, $crit); +} + +sub memhost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('summary.hardware.memorySize'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; + + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'mem.consumed.average', 'instances' => ['']}, + {'label' => 'mem.overhead.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $mem_used = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); + my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if ($mem_used * 100 / ($memory_size / 1024) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($mem_used * 100 / ($memory_size / 1024) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Memory used : " . simplify_number($mem_used / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; + $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_used * 1024) . "o"; + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# SwapHost Func +############ + +sub swaphost_check_args { + my ($host, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile("ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub swaphost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 0.8); + my $crit = (defined($_[2]) ? $_[2] : 1); + return ($lhost, $warn, $crit); +} + +sub swaphost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + return ; + } + + my %filters = ('name' => $lhost); + #my @properties = ('summary'); + my @properties = (); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, + {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $swap_in = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapinRate.average'}->{'key'} . ":"}[0])); + my $swap_out = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if (($swap_in / 1024) >= $warn || ($swap_out / 1024) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (($swap_in / 1024) >= $crit || ($swap_out / 1024) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; + $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + + +############ +# List Host Func +############ + +sub listhost_check_args { + return 0; +} + +sub listhost_compute_args { + return undef; +} + +sub listhost_do { + my ($lhost) = @_; + my %filters = (); + my @properties = ('name'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Host List: '; + my $output_append = ""; + + foreach my $entity_view (@$result) { + $output .= $output_append . $entity_view->{name}; + $output_append = ', '; + } + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# List Datastore Func +############ + +sub listdatastore_check_args { + return 0; +} + +sub listdatastore_compute_args { + return undef; +} + +sub listdatastore_do { + my ($ds, $warn, $crit) = @_; + my %filters = (); + my @properties = ('datastore'); + + my $result = get_entities_host('Datacenter', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @ds_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->datastore) { + @ds_array = (@ds_array, @{$entity_view->datastore}); + } + } + + @properties = ('summary'); + $result = get_views(\@ds_array, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Datastore List: '; + my $output_append = ""; + foreach my $datastore (@$result) { + if ($datastore->summary->accessible) { + $output .= $output_append . "'" . $datastore->summary->name . "'"; + $output_append = ', '; + } + } + + print $ERRORS{$MYERRORS{$status}} . "|$output\n"; +} + +############ +# List Host Func +############ + +sub listnichost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile("ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub listnichost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub listnichost_do { + my ($lhost) = @_; + my %filters = ('name' => $lhost); + my @properties = ('config.network.pnic'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output_up = 'Nic Up List: '; + my $output_down = 'Nic Down List: '; + my $output_up_append = ""; + my $output_down_append = ""; + foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($_->linkSpeed)) { + $output_up .= $output_up_append . "'" . $_->device . "'"; + $output_up_append = ', '; + } else { + $output_down .= $output_down_append . "'" . $_->device . "'"; + $output_down_append = ', '; + } + } + + print $ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"; +} + +############ + +sub catch_zap_term { + writeLogFile("$$ Receiving order to stop...\n"); + $stop = 1; +} + +sub REAPER { + my $child_pid; + + while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { + $return_child{$child_pid} = {'status' => 1, 'rtime' => time()}; + } + $SIG{CHLD} = \&REAPER; +} + +sub verify_child { + my $progress = 0; + + # Verify process + foreach (keys %child_proc) { + if (defined($return_child{$child_proc{$_}->{'pid'}}) && $return_child{$child_proc{$_}->{'pid'}}->{'status'} == 1) { + my $handle = ${$child_proc{$_}->{'reading'}}; + my $output = <$handle>; + close $handle; + if ($output =~ /^-1/) { + $last_time_check = $child_proc{$_}->{'ctime'}; + } + chomp $output; + $response_queue->enqueue("$_|$output\n"); + delete $return_child{$child_proc{$_}->{'pid'}}; + delete $child_proc{$_}; + } else { + # Check ctime + if (time() - $child_proc{$_}->{'ctime'} > $TIMEOUT) { + my $handle = ${$child_proc{$_}->{'reading'}}; + $response_queue->enqueue("$_|-1|Timeout Process.\n"); + kill('INT', $child_proc{$_}->{'pid'}); + close $handle; + delete $child_proc{$_}; + } else { + $progress++; + } + } + } + # Clean old hash CHILD (security) + foreach (keys %return_child) { + if (time() - $return_child{$_}->{'rtime'} > 600) { + writeLogFile("Clean Old return_child list = " . $_ . "\n"); + delete $return_child{$_}; + } + } + + return $progress; +} + +sub vsphere_handler { + while (1) { + if ($stop == 1) { + my $timeout_process = 0; + while ($timeout_process <= $TIMEOUT_KILL) { + if (!verify_child()) { + last; + } + $timeout_process++; + sleep(1); + } + if ($timeout_process > $TIMEOUT_KILL) { + writeLogFile("Kill child not gently.\n"); + foreach (keys %child_proc) { + kill('INT', $child_proc{$_}->{'pid'}); + } + } + + if ($vsphere_connected) { + eval { + Vim::logout(); + }; + } + $response_queue->enqueue("STOPPED\n"); + exit (0); + } + + + if (defined($last_time_vsphere) && defined($last_time_check) && $last_time_vsphere < $last_time_check) { + $vsphere_connected = 0; + eval { + Vim::logout(); + }; + } + if ($vsphere_connected == 0) { + if (!connect_vsphere()) { + writeLogFile("Vsphere connection ok\n"); + writeLogFile("Create perf counters cache in progress\n"); + if (!cache_perf_counters()) { + $last_time_vsphere = time(); + $keeper_session_time = time(); + $vsphere_connected = 1; + writeLogFile("Create perf counters cache done\n"); + } + } + } + + if (defined($keeper_session_time) && (time() - $keeper_session_time) > ($REFRESH_KEEPER_SESSION * 60)) { + my $stime; + + eval { + $stime = Vim::get_service_instance()->CurrentTime(); + $keeper_session_time = time(); + }; + if ($@) { + writeLogFile("$@"); + writeLogFile("Ask a new connection"); + # Ask a new connection + $last_time_check = time(); + } else { + writeLogFile("Get current time = " . Data::Dumper::Dumper($stime)); + } + } + + my $num_queued = $data_queue->pending(); + while ($num_queued) { + my $data_element = $data_queue->dequeue(); + chomp $data_element; + $num_queued--; + if ($data_element =~ /^STOP$/) { + $stop = 1; + next; + } + + my ($id) = split(/\|/, $data_element); + if ($vsphere_connected) { + writeLogFile("vpshere handler asking: $data_element\n"); + $child_proc{$id} = {'ctime' => time()}; + + my $reader; + my $writer; + pipe($reader, $writer); + $writer->autoflush(1); + + $child_proc{$id}->{'reading'} = \*$reader; + $child_proc{$id}->{'pid'} = fork; + if (!$child_proc{$id}->{'pid'}) { + # Child + close $reader; + open STDOUT, '>&', $writer; + my ($id, $name, @args) = split /\|/, $data_element; + $checks_descr{$name}->{'exec'}($checks_descr{$name}->{'compute'}(@args)); + exit(0); + } else { + # Parent + close $writer; + } + } else { + $response_queue->enqueue("$id|-1|Vsphere connection error."); + } + } + + verify_child(); + + if ($vsphere_connected == 0) { + sleep(5); + } else { + Time::HiRes::sleep(0.2); + } + } +} + +$SIG{TERM} = \&catch_zap_term; +$SIG{CHLD} = \&REAPER; + +open my $centesx_fh, '>>', $LOG; +open STDOUT, '>&', $centesx_fh; +open STDERR, '>&', $centesx_fh; + + +$data_queue = Thread::Queue->new(); +$response_queue = Thread::Queue->new(); +my $thr = threads->create(\&vsphere_handler); +$thr->detach(); + +my $server = IO::Socket::INET->new( Proto => "tcp", + LocalPort => $port, + Listen => SOMAXCONN, + Reuse => 1, + Timeout => 0.5); +if (!$server) { + writeLogFile("Can't setup server: $!\n"); + exit(1); +} +writeLogFile("[Server accepting clients]\n"); +while (1) { + my $client; + + if (!$stop) { + $client = $server->accept(); + } + if ($stop == 1) { + writeLogFile("Send STOP command to thread.\n"); + $data_queue->enqueue("STOP\n"); + $stop = 2; + } + ### + # Check + ### + my $num_queued = $response_queue->pending(); + while ($num_queued) { + my $data_element = $response_queue->dequeue(); + chomp $data_element; + if ($data_element =~ /^STOPPED$/) { + writeLogFile("Thread has stopped\n"); + exit(0); + } + # Verify responde queue + #print "Response queue = $data_element\n"; + my @results = split(/\|/, $data_element); + my $id = $results[0]; + $num_queued--; + if (!defined($sockets{$id})) { + writeLogFile("Too much time to get response.\n"); + next; + } + + writeLogFile("response = $data_element\n"); + $data_element =~ s/^.*?\|//; + ${$sockets{$id}->{'obj'}}->send($data_element . "\n"); + close ${$sockets{$id}->{"obj"}}; + delete $sockets{$id}; + } + foreach (keys %sockets) { + if (time() - $sockets{$_}->{'ctime'} > $TIMEOUT) { + writeLogFile("Timeout returns for uuid = '" . $sockets{$_}->{'uuid'} . "'.\n"); + ${$sockets{$_}->{'obj'}}->send("3|TIMEOUT\n"); + close ${$sockets{$_}->{"obj"}}; + delete $sockets{$_}; + } + } + + if (!$client) { + next; + } + my $uuid = $counter_request_id; + $counter_request_id++; + $client->autoflush(1); + my $hostinfo = gethostbyaddr($client->peeraddr); + #writeLogFile("[Connect from " . ($hostinfo ? $hostinfo->name : $client->peerhost) . "]\n"); + my $line = <$client>; + if (defined($line) && $line ne "") { + chomp $line; + my ($name, @args) = split /\|/, $line; + if (!defined($checks_descr{$name})) { + $client->send("3|Unknown method name '$name'\n"); + close $client; + next; + } + if ($checks_descr{$name}->{'arg'}(@args)) { + $client->send("3|Params error '$name'\n"); + close $client; + next; + } + + $sockets{$uuid} = {"obj" => \$client, "ctime" => time(), "uuid" => $uuid}; + $data_queue->enqueue("$uuid|$line\n"); + } else { + $client->send("3|Need arguments\n"); + close $client; + } +} + +exit(0); diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm new file mode 100644 index 000000000..721816da3 --- /dev/null +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -0,0 +1,11 @@ +our $port = 5700; +our $service_url = "https://srvi-vcenter.merethis.net/sdk"; +our $username = "xxxxx"; +our $password = 'xxxxx'; +our $TIMEOUT_VSPHERE = 60; +our $TIMEOUT = 60; +our $TIMEOUT_KILL = 30; +our $REFRESH_KEEPER_SESSION = 15; +our $LOG = "/tmp/centreon_esxd.log"; + +1; diff --git a/connectors/vmware/centreon_esxd-init b/connectors/vmware/centreon_esxd-init new file mode 100644 index 000000000..f20828402 --- /dev/null +++ b/connectors/vmware/centreon_esxd-init @@ -0,0 +1,113 @@ +#! /bin/bash +# +# centreon_esxd Start/Stop the centreon_esxd daemon. +# +# chkconfig: 2345 80 20 +# description: centreon_esxd is a Centreon program that manage Vpshere Checks +# processname: centreon_esxd +# config: /etc/centreon/centreon_esxd.pm +# pidfile: /var/run/centreon_esxd.pid + +# Source function library. +. /etc/init.d/functions + +binary=/usr/bin/centreon_esxd +servicename=$(basename "$0") +user=root +timeout=60 + +pidfile=/var/run/centreon_esxd.pid + +# Check if we can find the binary. +if [ ! -x $binary ]; then + echo -n $"Starting $servicename."; + failure $"Executable file $binary not found. Exiting." + echo + exit 2 +fi + +start() { + echo -n $"Starting $servicename: " + if [ -e "$pidfile" ] && [ -n "$(cat $pidfile)" ] && [ -e "/proc/`cat $pidfile`" ]; then + echo -n $"cannot start $servicename: $servicename is already running."; + failure $"cannot start $servicename: $servicename already running."; + echo + return 1 + fi + if [ ! -e "$pidfile" ] ; then + pid=$(pidofproc $binary) + if [ -n "$pid" ] ; then + echo -n $"cannot start $servicename: $servicename is already running."; + failure $"cannot start $servicename: $servicename already running."; + echo + return 1 + fi + fi + + if [ "$(id -u -n)" = "$user" ] ; then + daemon ''$binary' "'$config_file'" > /dev/null 2>&1 &' + else + daemon --user $user ''$binary' "'$config_file'" > /dev/null 2>&1 &' + fi + pid=$(pidofproc $binary) + RETVAL=$? + echo $pid > $pidfile + success $"service launched" + echo + return $RETVAL +} + +stop() { + echo -n $"Stopping $servicename: " + if [ ! -e "$pidfile" ] || [ -z "$(cat $pidfile)" ] ; then + killproc -d $timeout "$binary" + else + killproc -p "$pidfile" -d $timeout "$binary" + fi + RETVAL=$? + echo + return $RETVAL +} + +rhstatus() { + status -p "$pidfile" "$binary" +} + +restart() { + stop + start +} + +reload() { + echo -n $"Reloading $servicename daemon configuration: " + killproc -p "$pidfile" "$binary" -HUP + RETVAL=$? + echo + return $RETVAL +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + reload) + reload + ;; + status) + rhstatus + ;; + condrestart) + [ -f /var/lock/subsys/centreon_esxd ] && restart || : + ;; + *) + echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}" + exit 1 +esac + + From ada37bcdbe90fb453f172a46608f300090cc5eec Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 11 Sep 2012 10:26:23 +0000 Subject: [PATCH 002/447] Bug fix overhead metric git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@3 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index c3882d8b4..5275a05ed 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -763,7 +763,7 @@ sub memhost_do { } $output = "Memory used : " . simplify_number($mem_used / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; - $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_used * 1024) . "o"; + $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; print $ERRORS{$MYERRORS{$status}} . "|$output\n"; } From 8f7c4cbea43c145af46515bf553f69d04aedda62 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 11 Sep 2012 15:01:15 +0000 Subject: [PATCH 003/447] Bug fix race condition with thread::queue git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@6 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 5275a05ed..ca98a4537 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -1086,11 +1086,9 @@ sub vsphere_handler { } } - my $num_queued = $data_queue->pending(); - while ($num_queued) { - my $data_element = $data_queue->dequeue(); + my $data_element; + while (($data_element = $data_queue->dequeue_nb())) { chomp $data_element; - $num_queued--; if ($data_element =~ /^STOP$/) { $stop = 1; next; @@ -1171,9 +1169,9 @@ while (1) { ### # Check ### - my $num_queued = $response_queue->pending(); - while ($num_queued) { - my $data_element = $response_queue->dequeue(); + my $data_element; + + while (($data_element = $response_queue->dequeue_nb())) { chomp $data_element; if ($data_element =~ /^STOPPED$/) { writeLogFile("Thread has stopped\n"); @@ -1183,7 +1181,6 @@ while (1) { #print "Response queue = $data_element\n"; my @results = split(/\|/, $data_element); my $id = $results[0]; - $num_queued--; if (!defined($sockets{$id})) { writeLogFile("Too much time to get response.\n"); next; From e72a7a42a1cc3e42b6d07a06e0f8fc83c88960f7 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 13 Sep 2012 11:39:02 +0000 Subject: [PATCH 004/447] - Fix race condition with threads::queue git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@9 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 410 ++++++++++++++++++-------------- 1 file changed, 230 insertions(+), 180 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index ca98a4537..39efd64da 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -9,19 +9,15 @@ use VMware::VIRuntime; use VMware::VILib; use IO::Socket; use Net::hostent; # for OOish version of gethostbyaddr -use threads; -use Thread::Queue; +use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; -use Time::HiRes; use vars qw($port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION $LOG); require '/etc/centreon/centreon_esxd.pm'; our $session_id; -our $data_queue; -our $response_queue; our %sockets = (); our %child_proc; our %return_child; @@ -36,6 +32,15 @@ our $perfcounter_refreshrate = 20; our $perfcounter_speriod = -1; our $stop = 0; our $counter_request_id = 0; +our $child_vpshere_pid; +our $read_select; +our $reader_pipe_one; +our $writer_pipe_one; +our $reader_pipe_two; +our $writer_pipe_two; +our $session1; +our $counter = 0; +our $global_id; our %ERRORS = ( "OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" => 3, "PENDING" => 4); our %MYERRORS = (0 => "OK", 1 => "WARNING", 3 => "CRITICAL", 7 => "UNKNOWN"); @@ -66,7 +71,10 @@ sub connect_vsphere { eval { $SIG{ALRM} = sub { die('TIMEOUT'); }; alarm($TIMEOUT_VSPHERE); - Vim::login(service_url=> $service_url, user_name => $username, password => $password); + $session1 = Vim->new(service_url => $service_url); + $session1->login( + user_name => $username, + password => $password); alarm(0); }; if($@) { @@ -75,16 +83,20 @@ sub connect_vsphere { writeLogFile("Login to VirtualCentre server failed: $@"); return 1; } - eval { - $session_id = Vim::get_session_id(); - }; - if($@) { - writeLogFile("Can't get session_id: $@\n"); - 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; @@ -107,13 +119,13 @@ sub get_views { my $results; eval { - $results = Vim::get_views(mo_ref_array => $_[0], properties => $_[1]); + $results = $session1->get_views(mo_ref_array => $_[0], properties => $_[1]); }; if ($@) { writeLogFile("$@"); my $lerror = $@; $lerror =~ s/\n/ /g; - print "-1|Error: " . $lerror . "\n"; + print_response("-1|Error: " . $lerror . "\n"); return undef; } return $results; @@ -169,7 +181,7 @@ sub generic_performance_values_historic { sub cache_perf_counters { eval { - $perfmanager_view = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']); + $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}; @@ -196,29 +208,29 @@ sub get_entities_host { my $entity_views; eval { - $entity_views = Vim::find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; if ($@ =~ /decryption failed or bad record mac/) { writeLogFile("$@"); eval { - $entity_views = Vim::find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; if ($@) { my $lerror = $@; $lerror =~ s/\n/ /g; - print "-1|Error: " . $lerror . "\n"; + print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); return undef; } } elsif ($@) { writeLogFile("$@"); my $lerror = $@; $lerror =~ s/\n/ /g; - print "-1|Error: " . $lerror . "\n"; + print_response("-1|Error: " . $lerror . "\n"); return undef; } if (!@$entity_views) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Host does not exist.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|Host does not exist.\n"); return undef; } #eval { @@ -331,7 +343,7 @@ sub healthhost_do { $output = "All $OKCount health checks are green"; } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -419,7 +431,7 @@ sub datastores_do { $output = "Datastore '$ds' not found or summary not accessible."; $status |= $MYERRORS_MASK{'UNKNOWN'}; } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -461,7 +473,7 @@ sub maintenancehost_do { } } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -521,7 +533,7 @@ sub statushost_do { } } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -560,7 +572,7 @@ sub cpuhost_do { my ($lhost, $warn, $crit) = @_; if (!($perfcounter_speriod > 0)) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); return ; } @@ -604,7 +616,7 @@ sub cpuhost_do { $output .= " cpu$instance=" . simplify_number(convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; } } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -648,7 +660,7 @@ sub nethost_do { my ($lhost, $pnic, $warn, $crit) = @_; if (!($perfcounter_speriod > 0)) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); return ; } @@ -692,7 +704,7 @@ sub nethost_do { $output = "Traffic In : " . simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %), Out : " . simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %)"; $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -731,7 +743,7 @@ sub memhost_do { my ($lhost, $warn, $crit) = @_; if (!($perfcounter_speriod > 0)) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); return ; } @@ -765,7 +777,7 @@ sub memhost_do { $output = "Memory used : " . simplify_number($mem_used / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -804,7 +816,7 @@ sub swaphost_do { my ($lhost, $warn, $crit) = @_; if (!($perfcounter_speriod > 0)) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); return ; } @@ -836,7 +848,7 @@ sub swaphost_do { $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } @@ -870,7 +882,7 @@ sub listhost_do { $output_append = ', '; } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -918,7 +930,7 @@ sub listdatastore_do { } } - print $ERRORS{$MYERRORS{$status}} . "|$output\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } ############ @@ -963,7 +975,7 @@ sub listnichost_do { } } - print $ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"); } ############ @@ -987,28 +999,16 @@ sub verify_child { # Verify process foreach (keys %child_proc) { - if (defined($return_child{$child_proc{$_}->{'pid'}}) && $return_child{$child_proc{$_}->{'pid'}}->{'status'} == 1) { + # Check ctime + if (time() - $child_proc{$_}->{'ctime'} > $TIMEOUT) { my $handle = ${$child_proc{$_}->{'reading'}}; - my $output = <$handle>; + print $writer_pipe_one "$_|-1|Timeout Process.\n"; + kill('INT', $child_proc{$_}->{'pid'}); + $read_select->remove($handle); close $handle; - if ($output =~ /^-1/) { - $last_time_check = $child_proc{$_}->{'ctime'}; - } - chomp $output; - $response_queue->enqueue("$_|$output\n"); - delete $return_child{$child_proc{$_}->{'pid'}}; delete $child_proc{$_}; } else { - # Check ctime - if (time() - $child_proc{$_}->{'ctime'} > $TIMEOUT) { - my $handle = ${$child_proc{$_}->{'reading'}}; - $response_queue->enqueue("$_|-1|Timeout Process.\n"); - kill('INT', $child_proc{$_}->{'pid'}); - close $handle; - delete $child_proc{$_}; - } else { - $progress++; - } + $progress++; } } # Clean old hash CHILD (security) @@ -1023,37 +1023,40 @@ sub verify_child { } sub vsphere_handler { + my $timeout_process; + $read_select = new IO::Select(); + $read_select->add($reader_pipe_two); while (1) { - if ($stop == 1) { - my $timeout_process = 0; - while ($timeout_process <= $TIMEOUT_KILL) { - if (!verify_child()) { - last; - } - $timeout_process++; - sleep(1); - } - if ($timeout_process > $TIMEOUT_KILL) { - writeLogFile("Kill child not gently.\n"); - foreach (keys %child_proc) { - kill('INT', $child_proc{$_}->{'pid'}); - } - } + my $progress = verify_child(); + ##### + # Manage ending + ##### + if ($stop && $timeout_process > $TIMEOUT_KILL) { + writeLogFile("Kill child not gently.\n"); + foreach (keys %child_proc) { + kill('INT', $child_proc{$_}->{'pid'}); + } + $progress = 0; + } + if ($stop && !$progress) { if ($vsphere_connected) { eval { - Vim::logout(); + $session1->logout(); }; } - $response_queue->enqueue("STOPPED\n"); + print $writer_pipe_one "STOPPED\n"; exit (0); } - + ### + # Manage vpshere connection + ### if (defined($last_time_vsphere) && defined($last_time_check) && $last_time_vsphere < $last_time_check) { + writeLogFile("Deconnect\n"); $vsphere_connected = 0; eval { - Vim::logout(); + $session1->logout(); }; } if ($vsphere_connected == 0) { @@ -1069,11 +1072,14 @@ sub vsphere_handler { } } + ### + # Manage session time + ### if (defined($keeper_session_time) && (time() - $keeper_session_time) > ($REFRESH_KEEPER_SESSION * 60)) { my $stime; eval { - $stime = Vim::get_service_instance()->CurrentTime(); + $stime = $session1->get_service_instance()->CurrentTime(); $keeper_session_time = time(); }; if ($@) { @@ -1087,48 +1093,71 @@ sub vsphere_handler { } my $data_element; - while (($data_element = $data_queue->dequeue_nb())) { - chomp $data_element; - if ($data_element =~ /^STOP$/) { - $stop = 1; - next; - } - - my ($id) = split(/\|/, $data_element); - if ($vsphere_connected) { - writeLogFile("vpshere handler asking: $data_element\n"); - $child_proc{$id} = {'ctime' => time()}; - - my $reader; - my $writer; - pipe($reader, $writer); - $writer->autoflush(1); - - $child_proc{$id}->{'reading'} = \*$reader; - $child_proc{$id}->{'pid'} = fork; - if (!$child_proc{$id}->{'pid'}) { - # Child - close $reader; - open STDOUT, '>&', $writer; - my ($id, $name, @args) = split /\|/, $data_element; - $checks_descr{$name}->{'exec'}($checks_descr{$name}->{'compute'}(@args)); - exit(0); - } else { - # Parent - close $writer; - } - } else { - $response_queue->enqueue("$id|-1|Vsphere connection error."); - } - } - - verify_child(); - + my @rh_set; if ($vsphere_connected == 0) { sleep(5); - } else { - Time::HiRes::sleep(0.2); } + 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 ($rh == $reader_pipe_two && !$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("vpshere 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; + 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 $writer_pipe_one "$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 $writer_pipe_one "$lid|$output\n"; + delete $return_child{$child_proc{$lid}->{'pid'}}; + delete $child_proc{$lid}; + } + } } } @@ -1139,97 +1168,118 @@ open my $centesx_fh, '>>', $LOG; open STDOUT, '>&', $centesx_fh; open STDERR, '>&', $centesx_fh; - -$data_queue = Thread::Queue->new(); -$response_queue = Thread::Queue->new(); -my $thr = threads->create(\&vsphere_handler); -$thr->detach(); +pipe($reader_pipe_one, $writer_pipe_one); +pipe($reader_pipe_two, $writer_pipe_two); +$writer_pipe_one->autoflush(1); +$writer_pipe_two->autoflush(1); my $server = IO::Socket::INET->new( Proto => "tcp", LocalPort => $port, Listen => SOMAXCONN, - Reuse => 1, - Timeout => 0.5); + Reuse => 1); if (!$server) { writeLogFile("Can't setup server: $!\n"); exit(1); } + +$child_vpshere_pid = fork(); +if (!$child_vpshere_pid) { + close $reader_pipe_one; + close $writer_pipe_two; + vsphere_handler(); + exit(0); +} +close $writer_pipe_one; +close $reader_pipe_two; + +$read_select = new IO::Select(); +$read_select->add($server); +$read_select->add($reader_pipe_one); writeLogFile("[Server accepting clients]\n"); while (1) { - my $client; - if (!$stop) { - $client = $server->accept(); - } - if ($stop == 1) { + my @rh_set = $read_select->can_read(30); + if ($stop == 1) { writeLogFile("Send STOP command to thread.\n"); - $data_queue->enqueue("STOP\n"); + print $writer_pipe_two "STOP\n"; $stop = 2; } - ### - # Check - ### - my $data_element; - - while (($data_element = $response_queue->dequeue_nb())) { - chomp $data_element; - if ($data_element =~ /^STOPPED$/) { - writeLogFile("Thread has stopped\n"); - exit(0); - } - # Verify responde queue - #print "Response queue = $data_element\n"; - my @results = split(/\|/, $data_element); - my $id = $results[0]; - if (!defined($sockets{$id})) { - writeLogFile("Too much time to get response.\n"); - next; - } + foreach my $rh (@rh_set) { + if (!$stop && $rh == $server) { + my $client; - writeLogFile("response = $data_element\n"); - $data_element =~ s/^.*?\|//; - ${$sockets{$id}->{'obj'}}->send($data_element . "\n"); - close ${$sockets{$id}->{"obj"}}; - delete $sockets{$id}; + # 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 ($rh == $reader_pipe_one) { + # Return to read + my $data_element = <$rh>; + chomp $data_element; + if ($data_element =~ /^STOPPED$/) { + writeLogFile("Thread has stopped\n"); + exit(0); + } + # Verify responde queue + #print "Response queue = $data_element\n"; + my @results = split(/\|/, $data_element); + my ($id, $counter) = split(/\./, $results[0]); + if (!defined($sockets{$id}) || $counter != $sockets{$id}->{'counter'}) { + writeLogFile("Too much time to get response.\n"); + next; + } + + writeLogFile("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, @args) = split /\|/, $line; + if (!defined($checks_descr{$name})) { + $rh->send("3|Unknown method name '$name'\n"); + $read_select->remove($rh); + close $rh; + delete $sockets{fileno($rh)}; + next; + } + if ($checks_descr{$name}->{'arg'}(@args)) { + $rh->send("3|Params error '$name'\n"); + $read_select->remove($rh); + close $rh; + delete $sockets{fileno($rh)}; + next; + } + + print $writer_pipe_two fileno($rh) . "." . $sockets{fileno($rh)}->{'counter'} . "|$line\n"; + } else { + delete $sockets{fileno($rh)}; + $rh->send("3|Need arguments\n"); + $read_select->remove($rh); + close $rh; + } + } } + + # Verify socket foreach (keys %sockets) { if (time() - $sockets{$_}->{'ctime'} > $TIMEOUT) { - writeLogFile("Timeout returns for uuid = '" . $sockets{$_}->{'uuid'} . "'.\n"); + writeLogFile("Timeout returns.\n"); ${$sockets{$_}->{'obj'}}->send("3|TIMEOUT\n"); + $read_select->remove(${$sockets{$_}->{"obj"}}); close ${$sockets{$_}->{"obj"}}; delete $sockets{$_}; } } - if (!$client) { - next; - } - my $uuid = $counter_request_id; - $counter_request_id++; - $client->autoflush(1); - my $hostinfo = gethostbyaddr($client->peeraddr); - #writeLogFile("[Connect from " . ($hostinfo ? $hostinfo->name : $client->peerhost) . "]\n"); - my $line = <$client>; - if (defined($line) && $line ne "") { - chomp $line; - my ($name, @args) = split /\|/, $line; - if (!defined($checks_descr{$name})) { - $client->send("3|Unknown method name '$name'\n"); - close $client; - next; - } - if ($checks_descr{$name}->{'arg'}(@args)) { - $client->send("3|Params error '$name'\n"); - close $client; - next; - } - - $sockets{$uuid} = {"obj" => \$client, "ctime" => time(), "uuid" => $uuid}; - $data_queue->enqueue("$uuid|$line\n"); - } else { - $client->send("3|Need arguments\n"); - close $client; - } } exit(0); From 8c277b8947512e78c35ad8dbcd72abd7bbbb8692 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 13 Sep 2012 13:36:49 +0000 Subject: [PATCH 005/447] =?UTF-8?q?Evolution=20#3956=20Syst=C3=A8me=20de?= =?UTF-8?q?=20log=20plus=20=C3=A9volu=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@12 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 151 ++++++++++++++---------- connectors/vmware/centreon_esxd-conf.pm | 7 ++ 2 files changed, 96 insertions(+), 62 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 39efd64da..d874aa879 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -1,7 +1,13 @@ #!/usr/bin/perl -w + BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; + eval 'require Unix::Syslog;'; + if (!$@) { + require Unix::Syslog; + Unix::Syslog->import(qw(:subs :macros)); + } } use strict; @@ -13,7 +19,12 @@ use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; -use vars qw($port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION $LOG); +use vars qw($port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); +use vars qw($LOG $log_mode $log_crit $log_facility); +use constant { + LOG_ESXD_ERROR => 1, + LOG_ESXD_INFO => 2 +}; require '/etc/centreon/centreon_esxd.pm'; @@ -59,15 +70,25 @@ our %checks_descr = ( "listnichost" => {'arg' => \&listnichost_check_args, 'compute' => \&listnichost_compute_args, 'exec' => \&listnichost_do} ); -sub writeLogFile($){ - 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, $_[0]; - close LOG; +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 LOG_ERR, $_[1] if ($_[0] == LOG_ESXD_ERROR); + syslog LOG_INFO, $_[1] if ($_[0] == LOG_ESXD_INFO); + } } sub connect_vsphere { - writeLogFile("Vsphere connection in progress\n"); + writeLogFile(LOG_ESXD_INFO, "Vsphere connection in progress\n"); eval { $SIG{ALRM} = sub { die('TIMEOUT'); }; alarm($TIMEOUT_VSPHERE); @@ -78,9 +99,9 @@ sub connect_vsphere { alarm(0); }; if($@) { - writeLogFile("No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/); - writeLogFile("You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/); - writeLogFile("Login to VirtualCentre server failed: $@"); + writeLogFile(LOG_ESXD_ERROR, "No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/); + writeLogFile(LOG_ESXD_ERROR, "You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/); + writeLogFile(LOG_ESXD_ERROR, "Login to VirtualCentre server failed: $@"); return 1; } # eval { @@ -122,7 +143,7 @@ sub get_views { $results = $session1->get_views(mo_ref_array => $_[0], properties => $_[1]); }; if ($@) { - writeLogFile("$@"); + writeLogFile(LOG_ESXD_ERROR, "$@"); my $lerror = $@; $lerror =~ s/\n/ /g; print_response("-1|Error: " . $lerror . "\n"); @@ -143,7 +164,7 @@ sub get_perf_metric_ids { push @filtered_list, $metric; } } else { - writeLogFile("Metric '" . $_->{'label'} . "' unavailable.\n"); + writeLogFile(LOG_ESXD_ERROR, "Metric '" . $_->{'label'} . "' unavailable.\n"); } } return \@filtered_list; @@ -173,7 +194,7 @@ sub generic_performance_values_historic { } }; if ($@) { - writeLogFile($@); + writeLogFile(LOG_ESXD_ERROR, "$@"); return undef; } return \%results; @@ -197,7 +218,7 @@ sub cache_perf_counters { } }; if ($@) { - writeLogFile($@); + writeLogFile(LOG_ESXD_ERROR, "$@"); return 1; } return 0; @@ -211,18 +232,19 @@ sub get_entities_host { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; if ($@ =~ /decryption failed or bad record mac/) { - writeLogFile("$@"); + writeLogFile(LOG_ESXD_ERROR, "$@"); eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; if ($@) { + writeLogFile(LOG_ESXD_ERROR, "$@"); my $lerror = $@; $lerror =~ s/\n/ /g; print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); return undef; } } elsif ($@) { - writeLogFile("$@"); + writeLogFile(LOG_ESXD_ERROR, "$@"); my $lerror = $@; $lerror =~ s/\n/ /g; print_response("-1|Error: " . $lerror . "\n"); @@ -253,7 +275,7 @@ sub get_entities_host { sub healthhost_check_args { my ($host) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } return 0; @@ -353,19 +375,19 @@ sub healthhost_do { sub datastores_check_args { my ($ds, $warn, $crit) = @_; if (!defined($ds) || $ds eq "") { - writeLogFile("ARGS error: need datastore name\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); return 1; } if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: warn threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); return 1; } if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: crit threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); return 1; } if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); return 1; } return 0; @@ -441,7 +463,7 @@ sub datastores_do { sub maintenancehost_check_args { my ($host) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } return 0; @@ -483,7 +505,7 @@ sub maintenancehost_do { sub statushost_check_args { my ($host) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } return 0; @@ -543,19 +565,19 @@ sub statushost_do { sub cpuhost_check_args { my ($host, $warn, $crit) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: warn threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); return 1; } if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: crit threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); return 1; } if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); return 1; } return 0; @@ -626,23 +648,23 @@ sub cpuhost_do { sub nethost_check_args { my ($host, $pnic, $warn, $crit) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } if (!defined($pnic) || $pnic eq "") { - writeLogFile("ARGS error: need physical nic name\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need physical nic name\n"); return 1; } if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: warn threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); return 1; } if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: crit threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); return 1; } if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); return 1; } return 0; @@ -714,19 +736,19 @@ sub nethost_do { sub memhost_check_args { my ($host, $warn, $crit) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: warn threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); return 1; } if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: crit threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); return 1; } if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); return 1; } return 0; @@ -787,19 +809,19 @@ sub memhost_do { sub swaphost_check_args { my ($host, $warn, $crit) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: warn threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); return 1; } if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile("ARGS error: crit threshold must be a positive number\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); return 1; } if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile("ARGS error: warn threshold must be lower than crit threshold\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); return 1; } return 0; @@ -940,7 +962,7 @@ sub listdatastore_do { sub listnichost_check_args { my ($host) = @_; if (!defined($host) || $host eq "") { - writeLogFile("ARGS error: need hostname\n"); + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; } return 0; @@ -981,7 +1003,7 @@ sub listnichost_do { ############ sub catch_zap_term { - writeLogFile("$$ Receiving order to stop...\n"); + writeLogFile(LOG_ESXD_INFO, "$$ Receiving order to stop...\n"); $stop = 1; } @@ -1014,7 +1036,7 @@ sub verify_child { # Clean old hash CHILD (security) foreach (keys %return_child) { if (time() - $return_child{$_}->{'rtime'} > 600) { - writeLogFile("Clean Old return_child list = " . $_ . "\n"); + writeLogFile(LOG_ESXD_INFO, "Clean Old return_child list = " . $_ . "\n"); delete $return_child{$_}; } } @@ -1033,7 +1055,7 @@ sub vsphere_handler { # Manage ending ##### if ($stop && $timeout_process > $TIMEOUT_KILL) { - writeLogFile("Kill child not gently.\n"); + writeLogFile(LOG_ESXD_ERROR, "Kill child not gently.\n"); foreach (keys %child_proc) { kill('INT', $child_proc{$_}->{'pid'}); } @@ -1053,7 +1075,7 @@ sub vsphere_handler { # Manage vpshere connection ### if (defined($last_time_vsphere) && defined($last_time_check) && $last_time_vsphere < $last_time_check) { - writeLogFile("Deconnect\n"); + writeLogFile(LOG_ESXD_ERROR, "Deconnect\n"); $vsphere_connected = 0; eval { $session1->logout(); @@ -1061,13 +1083,13 @@ sub vsphere_handler { } if ($vsphere_connected == 0) { if (!connect_vsphere()) { - writeLogFile("Vsphere connection ok\n"); - writeLogFile("Create perf counters cache in progress\n"); + writeLogFile(LOG_ESXD_INFO, "Vsphere connection ok\n"); + writeLogFile(LOG_ESXD_INFO, "Create perf counters cache in progress\n"); if (!cache_perf_counters()) { $last_time_vsphere = time(); $keeper_session_time = time(); $vsphere_connected = 1; - writeLogFile("Create perf counters cache done\n"); + writeLogFile(LOG_ESXD_INFO, "Create perf counters cache done\n"); } } } @@ -1083,12 +1105,12 @@ sub vsphere_handler { $keeper_session_time = time(); }; if ($@) { - writeLogFile("$@"); - writeLogFile("Ask a new connection"); + writeLogFile(LOG_ESXD_ERROR, "$@"); + writeLogFile(LOG_ESXD_ERROR, "Ask a new connection"); # Ask a new connection $last_time_check = time(); } else { - writeLogFile("Get current time = " . Data::Dumper::Dumper($stime)); + writeLogFile(LOG_ESXD_INFO, "Get current time = " . Data::Dumper::Dumper($stime)); } } @@ -1116,7 +1138,7 @@ sub vsphere_handler { my ($id) = split(/\|/, $data_element); if ($vsphere_connected) { - writeLogFile("vpshere handler asking: $data_element\n"); + writeLogFile(LOG_ESXD_INFO, "vpshere handler asking: $data_element\n"); $child_proc{$id} = {'ctime' => time()}; my $reader; @@ -1164,9 +1186,14 @@ sub vsphere_handler { $SIG{TERM} = \&catch_zap_term; $SIG{CHLD} = \&REAPER; -open my $centesx_fh, '>>', $LOG; -open STDOUT, '>&', $centesx_fh; -open STDERR, '>&', $centesx_fh; +if ($log_mode == 1) { + open my $centesx_fh, '>>', $LOG; + open STDOUT, '>&', $centesx_fh; + open STDERR, '>&', $centesx_fh; +} +if ($log_mode == 2) { + openlog $0, LOG_PID, $log_facility; +} pipe($reader_pipe_one, $writer_pipe_one); pipe($reader_pipe_two, $writer_pipe_two); @@ -1178,7 +1205,7 @@ my $server = IO::Socket::INET->new( Proto => "tcp", Listen => SOMAXCONN, Reuse => 1); if (!$server) { - writeLogFile("Can't setup server: $!\n"); + writeLogFile(LOG_ESXD_ERROR, "Can't setup server: $!\n"); exit(1); } @@ -1195,12 +1222,12 @@ close $reader_pipe_two; $read_select = new IO::Select(); $read_select->add($server); $read_select->add($reader_pipe_one); -writeLogFile("[Server accepting clients]\n"); +writeLogFile(LOG_ESXD_INFO, "[Server accepting clients]\n"); while (1) { my @rh_set = $read_select->can_read(30); if ($stop == 1) { - writeLogFile("Send STOP command to thread.\n"); + writeLogFile(LOG_ESXD_INFO, "Send STOP command to thread.\n"); print $writer_pipe_two "STOP\n"; $stop = 2; } @@ -1220,7 +1247,7 @@ while (1) { my $data_element = <$rh>; chomp $data_element; if ($data_element =~ /^STOPPED$/) { - writeLogFile("Thread has stopped\n"); + writeLogFile(LOG_ESXD_INFO, "Thread has stopped\n"); exit(0); } # Verify responde queue @@ -1228,11 +1255,11 @@ while (1) { my @results = split(/\|/, $data_element); my ($id, $counter) = split(/\./, $results[0]); if (!defined($sockets{$id}) || $counter != $sockets{$id}->{'counter'}) { - writeLogFile("Too much time to get response.\n"); + writeLogFile(LOG_ESXD_INFO, "Too much time to get response.\n"); next; } - writeLogFile("response = $data_element\n"); + writeLogFile(LOG_ESXD_INFO, "response = $data_element\n"); $data_element =~ s/^.*?\|//; ${$sockets{$id}->{'obj'}}->send($data_element . "\n"); $read_select->remove(${$sockets{$id}->{"obj"}}); @@ -1272,7 +1299,7 @@ while (1) { # Verify socket foreach (keys %sockets) { if (time() - $sockets{$_}->{'ctime'} > $TIMEOUT) { - writeLogFile("Timeout returns.\n"); + writeLogFile(LOG_ESXD_INFO, "Timeout returns.\n"); ${$sockets{$_}->{'obj'}}->send("3|TIMEOUT\n"); $read_select->remove(${$sockets{$_}->{"obj"}}); close ${$sockets{$_}->{"obj"}}; diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index 721816da3..3f85dfb6e 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -6,6 +6,13 @@ 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, 2 = all +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; From cae8e0ccbc03d28b5fa189f3bb77a9833e3964b0 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 13 Sep 2012 15:22:15 +0000 Subject: [PATCH 006/447] Evolution #3959 Commande de cartographie git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@13 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 732 ++++++++++++----------- connectors/vmware/centreon_esxd | 63 +- 2 files changed, 432 insertions(+), 363 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 727f7a95f..5f2069b04 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -1,359 +1,373 @@ -#!/usr/bin/perl -w - -use strict; -no strict "refs"; -use IO::Socket; -use Getopt::Long; - -my $PROGNAME = $0; -my $VERSION = "1.0"; -my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); -my $socket; - -sub print_help(); -sub print_usage(); -sub print_revision($$); - -my %OPTION = ( - "help" => undef, "version" => undef, - "esxd-host" => undef, "esxd-port" => 5700, - "usage" => undef, - "esx-host" => undef, - "datastore" => undef, - "nic" => undef, - "warning" => undef, - "critical" => undef -); - -Getopt::Long::Configure('bundling'); -GetOptions( - "h|help" => \$OPTION{'help'}, - "V|version" => \$OPTION{'version'}, - "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, - "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, - - "u|usage=s" => \$OPTION{'usage'}, - "e|esx-host=s" => \$OPTION{'esx-host'}, - - "datastore=s" => \$OPTION{'datastore'}, - "nic=s" => \$OPTION{'nic'}, - - "w|warning=i" => \$OPTION{'warning'}, - "c|critical=i" => \$OPTION{'critical'}, -); - -if (defined($OPTION{'version'})) { - print_revision($PROGNAME, $VERSION); - exit $ERRORS{'OK'}; -} - -if (defined($OPTION{'help'})) { - print_help(); - exit $ERRORS{'OK'}; -} - -############# -# Functions # -############# - -sub print_usage () { - print "Usage: "; - print $PROGNAME."\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; - print " -H centreon-esxd Host (required)\n"; - print " -P centreon-esxd Port (default 5700)\n"; - print " -u (--usage) What to check. The list and args (required)\n"; - print "\n"; - print "'healthhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'maintenancehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'statushost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'datastores':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'cpuhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'nethost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --nic Physical nic name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'memhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'swaphost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; - print "'listhost':\n"; - print " None\n"; - print "\n"; - print "'listdatastore':\n"; - print " None\n"; - print "\n"; - print "'listnichost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2005-2012 Centreon #\n"; - print "# Bugs to http://redmine.merethis.net/ #\n"; - print "##############################################\n"; - print "\n"; - print_usage(); - print "\n"; -} - -sub print_revision($$) { - my $commandName = shift; - my $pluginRevision = shift; - print "$commandName v$pluginRevision (centreon-esxd)\n"; -} - -sub myconnect { - if (!($socket = IO::Socket::INET->new( Proto => "tcp", - PeerAddr => $OPTION{'esxd-host'}, - PeerPort => $OPTION{'esxd-port'}))) { - print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; - exit $ERRORS{'UNKNOWN'}; - } - $socket->autoflush(1); -} - -################# -# Func Usage -################# - -sub maintenancehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; -} - -sub maintenancehost_get_str { - return "maintenancehost|" . $OPTION{'esx-host'}; -} - -sub statushost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; -} - -sub statushost_get_str { - return "statushost|" . $OPTION{'esx-host'}; -} - -sub healthhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; -} - -sub healthhost_get_str { - return "healthhost|" . $OPTION{'esx-host'}; -} - -sub datastores_check_arg { - if (!defined($OPTION{'datastore'})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; -} - -sub datastores_get_str { - return "datastores|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; -} - -sub cpuhost_check_arg { - - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; -} - -sub cpuhost_get_str { - return "cpuhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; -} - -sub memhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; -} - -sub memhost_get_str { - return "memhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; -} - -sub swaphost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 0.8; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 1; - } - return 0; -} - -sub swaphost_get_str { - return "swaphost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; -} - -sub nethost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'nic'})) { - print "Option --nic is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; -} - -sub nethost_get_str { - return "nethost|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; -} - -sub listhost_check_arg { - return 0; -} - -sub listhost_get_str { - return "listhost"; -} - -sub listdatastore_check_arg { - return 0; -} - -sub listdatastore_get_str { - return "listdatastore"; -} - -sub listnichost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; -} - -sub listnichost_get_str { - return "listnichost|" . $OPTION{'esx-host'}; -} - -################# -################# - -if (!defined($OPTION{'esxd-host'})) { - print "Option -H (--esxd-host) is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; -} - -if (!defined($OPTION{'usage'})) { - print "Option -u (--usage) is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; -} -if ($OPTION{'usage'} !~ /^(healthhost|datastores|maintenancehost|statushost|cpuhost|nethost|memhost|swaphost|listhost|listdatastore|listnichost)$/) { - print "Usage value is unknown\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; -} - -my $func_check_arg = $OPTION{'usage'} . "_check_arg"; -my $func_get_str = $OPTION{'usage'} . "_get_str"; -&$func_check_arg(); -my $str_send = &$func_get_str(); -myconnect(); -print $socket "$str_send\n"; -my $return = <$socket>; -close $socket; - -chomp $return; -$return =~ /^(-?[0-9]*?)\|/; -my $status_return = $1; -$return =~ s/^(-?[0-9]*?)\|//; -print $return . "\n"; - -if ($status_return == -1) { - $status_return = 3; -} -exit $status_return; - -#print $remote "healthhost|srvi-esx-dev-1.merethis.net\n"; -#print $remote "datastores|LUN-VMFS-QGARNIER|80|90\n"; -#print $remote "maintenancehost|srvi-esx-dev-1.merethis.net\n"; -#print $remote "statushost|srvi-esx-dev-1.merethis.net\n"; -#print $remote "cpuhost|srvi-esx-dev-1.merethis.net|60\n"; -#print $remote "nethost|srvi-esx-dev-1.merethis.net|vmnic1|60\n"; -#print $remote "memhost|srvi-esx-dev-1.merethis.net|80\n"; -#print $remote "swaphost|srvi-esx-dev-1.merethis.net|80\n"; +#!/usr/bin/perl -w + +use strict; +no strict "refs"; +use IO::Socket; +use Getopt::Long; + +my $PROGNAME = $0; +my $VERSION = "1.0"; +my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); +my $socket; + +sub print_help(); +sub print_usage(); +sub print_revision($$); + +my %OPTION = ( + "help" => undef, "version" => undef, + "esxd-host" => undef, "esxd-port" => 5700, + "usage" => undef, + "esx-host" => undef, + "datastore" => undef, + "nic" => undef, + "warning" => undef, + "critical" => undef +); + +Getopt::Long::Configure('bundling'); +GetOptions( + "h|help" => \$OPTION{'help'}, + "V|version" => \$OPTION{'version'}, + "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, + "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, + + "u|usage=s" => \$OPTION{'usage'}, + "e|esx-host=s" => \$OPTION{'esx-host'}, + + "datastore=s" => \$OPTION{'datastore'}, + "nic=s" => \$OPTION{'nic'}, + + "w|warning=i" => \$OPTION{'warning'}, + "c|critical=i" => \$OPTION{'critical'}, +); + +if (defined($OPTION{'version'})) { + print_revision($PROGNAME, $VERSION); + exit $ERRORS{'OK'}; +} + +if (defined($OPTION{'help'})) { + print_help(); + exit $ERRORS{'OK'}; +} + +############# +# Functions # +############# + +sub print_usage () { + print "Usage: "; + print $PROGNAME."\n"; + print " -V (--version) Plugin version\n"; + print " -h (--help) usage help\n"; + print " -H centreon-esxd Host (required)\n"; + print " -P centreon-esxd Port (default 5700)\n"; + print " -u (--usage) What to check. The list and args (required)\n"; + print "\n"; + print "'healthhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'maintenancehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'statushost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'datastores':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'cpuhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'nethost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " --nic Physical nic name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'memhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'swaphost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; + print "'listhost':\n"; + print " None\n"; + print "\n"; + print "'listdatastore':\n"; + print " None\n"; + print "\n"; + print "'listnichost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'getmap':\n"; + print " -e (--esx-host) Esx Host to check\n"; +} + +sub print_help () { + print "##############################################\n"; + print "# Copyright (c) 2005-2012 Centreon #\n"; + print "# Bugs to http://redmine.merethis.net/ #\n"; + print "##############################################\n"; + print "\n"; + print_usage(); + print "\n"; +} + +sub print_revision($$) { + my $commandName = shift; + my $pluginRevision = shift; + print "$commandName v$pluginRevision (centreon-esxd)\n"; +} + +sub myconnect { + if (!($socket = IO::Socket::INET->new( Proto => "tcp", + PeerAddr => $OPTION{'esxd-host'}, + PeerPort => $OPTION{'esxd-port'}))) { + print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; + exit $ERRORS{'UNKNOWN'}; + } + $socket->autoflush(1); +} + +################# +# Func Usage +################# + +sub maintenancehost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub maintenancehost_get_str { + return "maintenancehost|" . $OPTION{'esx-host'}; +} + +sub statushost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub statushost_get_str { + return "statushost|" . $OPTION{'esx-host'}; +} + +sub healthhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub healthhost_get_str { + return "healthhost|" . $OPTION{'esx-host'}; +} + +sub datastores_check_arg { + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub datastores_get_str { + return "datastores|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub cpuhost_check_arg { + + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub cpuhost_get_str { + return "cpuhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub memhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub memhost_get_str { + return "memhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub swaphost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 0.8; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 1; + } + return 0; +} + +sub swaphost_get_str { + return "swaphost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub nethost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'nic'})) { + print "Option --nic is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub nethost_get_str { + return "nethost|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub listhost_check_arg { + return 0; +} + +sub listhost_get_str { + return "listhost"; +} + +sub listdatastore_check_arg { + return 0; +} + +sub listdatastore_get_str { + return "listdatastore"; +} + +sub listnichost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub listnichost_get_str { + return "listnichost|" . $OPTION{'esx-host'}; +} + +sub getmap_check_arg { + if (!defined($OPTION{'esx-host'})) { + $OPTION{'esx-host'} = ""; + } + return 0; +} + +sub getmap_get_str { + return "getmap|" . $OPTION{'esx-host'}; +} + +################# +################# + +if (!defined($OPTION{'esxd-host'})) { + print "Option -H (--esxd-host) is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} + +if (!defined($OPTION{'usage'})) { + print "Option -u (--usage) is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} +if ($OPTION{'usage'} !~ /^(healthhost|datastores|maintenancehost|statushost|cpuhost|nethost|memhost|swaphost|listhost|listdatastore|listnichost|getmap)$/) { + print "Usage value is unknown\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} + +my $func_check_arg = $OPTION{'usage'} . "_check_arg"; +my $func_get_str = $OPTION{'usage'} . "_get_str"; +&$func_check_arg(); +my $str_send = &$func_get_str(); +myconnect(); +print $socket "$str_send\n"; +my $return = <$socket>; +close $socket; + +chomp $return; +$return =~ /^(-?[0-9]*?)\|/; +my $status_return = $1; +$return =~ s/^(-?[0-9]*?)\|//; +print $return . "\n"; + +if ($status_return == -1) { + $status_return = 3; +} +exit $status_return; + +#print $remote "healthhost|srvi-esx-dev-1.merethis.net\n"; +#print $remote "datastores|LUN-VMFS-QGARNIER|80|90\n"; +#print $remote "maintenancehost|srvi-esx-dev-1.merethis.net\n"; +#print $remote "statushost|srvi-esx-dev-1.merethis.net\n"; +#print $remote "cpuhost|srvi-esx-dev-1.merethis.net|60\n"; +#print $remote "nethost|srvi-esx-dev-1.merethis.net|vmnic1|60\n"; +#print $remote "memhost|srvi-esx-dev-1.merethis.net|80\n"; +#print $remote "swaphost|srvi-esx-dev-1.merethis.net|80\n"; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index d874aa879..da8d76bb8 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -67,7 +67,8 @@ our %checks_descr = ( "swaphost" => {'arg' => \&swaphost_check_args, 'compute' => \&swaphost_compute_args, 'exec' => \&swaphost_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} + "listnichost" => {'arg' => \&listnichost_check_args, 'compute' => \&listnichost_compute_args, 'exec' => \&listnichost_do}, + "getmap" => {'arg' => \&getmap_check_args, 'compute' => \&getmap_compute_args, 'exec' => \&getmap_do} ); sub writeLogFile($$) { @@ -887,7 +888,6 @@ sub listhost_compute_args { } sub listhost_do { - my ($lhost) = @_; my %filters = (); my @properties = ('name'); my $result = get_entities_host('HostSystem', \%filters, \@properties); @@ -1000,6 +1000,61 @@ sub listnichost_do { print_response($ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"); } +############ +# Get Map Func +############ + +sub getmap_check_args { + return 0; +} + +sub getmap_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub getmap_do { + my ($lhost) = @_; + my %filters = (); + if (defined($lhost) and $lhost ne "") { + %filters = ('name' => $lhost); + } + my @properties = ('name', 'vm'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + my $output_append = ""; + + foreach my $entity_view (@$result) { + $output .= $output_append . "ESX Host '" . $entity_view->name . "': "; + my @vm_array = (); + if (defined $entity_view->vm) { + @vm_array = (@vm_array, @{$entity_view->vm}); + } + + @properties = ('name', 'summary.runtime.powerState'); + my $result2 = get_views(\@vm_array, \@properties); + if (!defined($result)) { + return ; + } + + my $output_append2 = ''; + foreach my $vm (@$result2) { + if ($vm->{'summary.runtime.powerState'}->val eq "poweredOn") { + $output .= $output_append2 . "[" . $vm->name . "]"; + $output_append2 = ', '; + } + } + $output_append = ". "; + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + ############ sub catch_zap_term { @@ -1273,16 +1328,16 @@ while (1) { my ($name, @args) = split /\|/, $line; if (!defined($checks_descr{$name})) { $rh->send("3|Unknown method name '$name'\n"); + delete $sockets{fileno($rh)}; $read_select->remove($rh); close $rh; - delete $sockets{fileno($rh)}; next; } if ($checks_descr{$name}->{'arg'}(@args)) { $rh->send("3|Params error '$name'\n"); + delete $sockets{fileno($rh)}; $read_select->remove($rh); close $rh; - delete $sockets{fileno($rh)}; next; } From bf38da172a0b9a107b872d6d4c4273d6974c83e6 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 19 Sep 2012 16:02:47 +0000 Subject: [PATCH 007/447] Commit for 1.1 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@14 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 60 +++++- connectors/vmware/centreon_esxd | 250 +++++++++++++++++++---- connectors/vmware/centreon_esxd-conf.pm | 4 +- 3 files changed, 266 insertions(+), 48 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 5f2069b04..603e6ed9b 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -74,11 +74,16 @@ sub print_usage () { print "'statushost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; print "\n"; - print "'datastores':\n"; + print "'datastore-usage':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; print " -c (--critical) Critical Threshold in percent (default 90)\n"; print "\n"; + print "'datastore-io':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in kBps (default none)\n"; + print " -c (--critical) Critical Threshold in kBps (default none)\n"; + print "\n"; print "'cpuhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; @@ -100,6 +105,11 @@ sub print_usage () { print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; print "\n"; + print "'datastoreshost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; + print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -182,7 +192,7 @@ sub healthhost_get_str { return "healthhost|" . $OPTION{'esx-host'}; } -sub datastores_check_arg { +sub datastoreusage_check_arg { if (!defined($OPTION{'datastore'})) { print "Option --datastore is required\n"; print_usage(); @@ -197,12 +207,30 @@ sub datastores_check_arg { return 0; } -sub datastores_get_str { - return "datastores|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +sub datastoreusage_get_str { + return "datastoreusage|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + +sub datastoreio_check_arg { + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + return 0; +} + +sub datastoreio_get_str { + return "datastoreio|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub cpuhost_check_arg { - if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); @@ -221,6 +249,25 @@ sub cpuhost_get_str { return "cpuhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub datastoreshost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + return 0; +} + +sub datastoreshost_get_str { + return "datastoreshost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + sub memhost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; @@ -337,12 +384,13 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastores|maintenancehost|statushost|cpuhost|nethost|memhost|swaphost|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|listhost|listdatastore|listnichost|getmap)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; } +$OPTION{'usage'} =~ s/-//g; my $func_check_arg = $OPTION{'usage'} . "_check_arg"; my $func_get_str = $OPTION{'usage'} . "_get_str"; &$func_check_arg(); diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index da8d76bb8..e5f9704a6 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -14,6 +14,7 @@ use strict; use VMware::VIRuntime; use VMware::VILib; use IO::Socket; +use File::Basename; use Net::hostent; # for OOish version of gethostbyaddr use IO::Select; use POSIX ":sys_wait_h"; @@ -58,11 +59,13 @@ 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}, - "datastores" => {'arg' => \&datastores_check_args, 'compute' => \&datastores_compute_args, 'exec' => \&datastores_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}, "listhost" => {'arg' => \&listhost_check_args, 'compute' => \&listhost_compute_args, 'exec' => \&listhost_do}, @@ -75,6 +78,7 @@ sub writeLogFile($$) { if (($log_crit & $_[0]) == 0) { return ; } + if ($log_mode == 0) { print $_[1]; } elsif ($log_mode == 1) { @@ -253,7 +257,7 @@ sub get_entities_host { } if (!@$entity_views) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Host does not exist.\n"); + print_response($ERRORS{$MYERRORS{$status}} . "|Object $view_type does not exist.\n"); return undef; } #eval { @@ -370,10 +374,10 @@ sub healthhost_do { } ############ -# Datastores Function +# DatastoreUsage Function ############ -sub datastores_check_args { +sub datastoreusage_check_args { my ($ds, $warn, $crit) = @_; if (!defined($ds) || $ds eq "") { writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); @@ -394,50 +398,29 @@ sub datastores_check_args { return 0; } -sub datastores_compute_args { +sub datastoreusage_compute_args { my $ds = $_[0]; my $warn = (defined($_[1]) ? $_[1] : 80); my $crit = (defined($_[2]) ? $_[2] : 90); return ($ds, $warn, $crit); } -sub datastores_do { +sub datastoreusage_do { my ($ds, $warn, $crit) = @_; - my %filters = (); - my @properties = ('datastore'); + my %filters = ('summary.name' => $ds); + my @properties = ('summary'); - my $result = get_entities_host('Datacenter', \%filters, \@properties); + my $result = get_entities_host('Datastore', \%filters, \@properties); if (!defined($result)) { return ; } - my @ds_array = (); - foreach my $entity_view (@$result) { - if (defined $entity_view->datastore) { - @ds_array = (@ds_array, @{$entity_view->datastore}); - } - } - - @properties = ('summary'); - $result = get_views(\@ds_array, \@properties); - if (!defined($result)) { - return ; - } - - my $ds_find; - foreach my $datastore (@$result) { - if ($datastore->summary->accessible && $datastore->summary->name eq $ds) { - $ds_find = $datastore; - last; - } - } - - my $output = ''; my $status = 0; # OK - if (defined($ds_find)) { - my $dsName = $ds_find->summary->name; - my $capacity = $ds_find->summary->capacity; - my $free = $ds_find->summary->freeSpace; + my $output = ""; + if ($$result[0]->summary->accessible == 1) { + my $dsName = $$result[0]->summary->name; + my $capacity = $$result[0]->summary->capacity; + my $free = $$result[0]->summary->freeSpace; my $pct = ($capacity - $free) / $capacity * 100; my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; @@ -451,12 +434,83 @@ sub datastores_do { $status |= $MYERRORS_MASK{'CRITICAL'}; } } else { - $output = "Datastore '$ds' not found or summary not accessible."; + $output = "Datastore '$ds' summary not accessible."; $status |= $MYERRORS_MASK{'UNKNOWN'}; } print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } +############ +# DatastoreIO Func +############ + +sub datastoreio_check_args { + my ($ds, $warn, $crit) = @_; + if (!defined($ds) || $ds eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub datastoreio_compute_args { + my $ds = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : ''); + my $crit = (defined($_[2]) ? $_[2] : ''); + return ($ds, $warn, $crit); +} + +sub datastoreio_do { + my ($ds, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('summary.name' => $ds); + my @properties = ('summary.name'); + my $result = get_entities_host('Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'datastore.read.average', 'instances' => ['']}, + {'label' => 'datastore.write.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.read.average'}->{'key'} . ":"}[0])); + my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.write.average'}->{'key'} . ":"}[0])); + + my $status = 0; # OK + my $output = ''; + + if ((defined($warn) && $warn ne "") && ($read_counter >= $warn || $write_counter >= $warn)) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ((defined($crit) && $crit ne "") && ($read_counter >= $crit || $write_counter >= $crit)) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Rate of reading data : " . simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . simplify_number($write_counter / 1024 * 8) . " Mb/s"; + $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + ############ # Maintenance Func ############ @@ -607,10 +661,6 @@ sub cpuhost_do { } my @instances = ('*'); - foreach my $index (0..($$result[0]->{'hardware.cpuInfo.numCpuThreads'} - 1)) { - push @instances, $index; - } - my $values = generic_performance_values_historic($$result[0], [{'label' => 'cpu.usage.average', 'instances' => \@instances}], @@ -730,6 +780,124 @@ sub nethost_do { print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); } +############ +# DiskHost Func +############ + +sub datastoreshost_check_args { + my ($lhost, $warn, $crit) = @_; + if (!defined($lhost) || $lhost eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub datastoreshost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : ''); + my $crit = (defined($_[2]) ? $_[2] : ''); + return ($lhost, $warn, $crit); +} + +sub datastoreshost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('config.fileSystemVolume.mountInfo'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my %uuid_list = (); + my %disk_name = (); + foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { + if ($_->volume->isa('HostVmfsVolume')) { + $uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + #foreach my $extent (@{$_->volume->extent}) { + # $disk_name{$extent->diskName} = $_->volume->name; + #} + } + if ($_->volume->isa('HostNasVolume')) { + $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; + } + } + + # Vsphere >= 4.1 + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, + {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], + $perfcounter_speriod); + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $perfdata = ''; + foreach (keys %uuid_list) { + if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and + defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { + my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); + my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); + if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + + $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; + } + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Latency counter: $output_warning"; + } + if ($status == 0) { + $output = "All Datastore latency counters are ok"; + } + print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); +} + + ############ # MemHost Func ############ @@ -1208,6 +1376,8 @@ sub vsphere_handler { # 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)); diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index 3f85dfb6e..4b613d4e2 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -1,5 +1,5 @@ our $port = 5700; -our $service_url = "https://srvi-vcenter.merethis.net/sdk"; +our $service_url = "https://XXXX.XXXX.XXX/sdk"; our $username = "xxxxx"; our $password = 'xxxxx'; our $TIMEOUT_VSPHERE = 60; @@ -8,7 +8,7 @@ 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, 2 = all +# 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; From 9d0199eac57c61e1cd700eb7a69e2397a82a769b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 20 Sep 2012 14:34:18 +0000 Subject: [PATCH 008/447] Evolution #3994 Splitter les commandes dans des sous fichiers git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@15 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 1168 +---------------- connectors/vmware/centreon_esxd-conf.pm | 2 + connectors/vmware/lib/command-cpuhost.pm | 76 ++ connectors/vmware/lib/command-datastoreio.pm | 68 + .../vmware/lib/command-datastoreshost.pm | 114 ++ .../vmware/lib/command-datastoreusage.pm | 64 + connectors/vmware/lib/command-getmap.pm | 53 + connectors/vmware/lib/command-healthhost.pm | 97 ++ .../vmware/lib/command-listdatastore.pm | 45 + connectors/vmware/lib/command-listhost.pm | 30 + connectors/vmware/lib/command-listnichost.pm | 43 + .../vmware/lib/command-maintenancehost.pm | 39 + connectors/vmware/lib/command-memhost.pm | 70 + connectors/vmware/lib/command-nethost.pm | 86 ++ connectors/vmware/lib/command-statushost.pm | 57 + connectors/vmware/lib/command-swaphost.pm | 68 + connectors/vmware/lib/esxd-common.pm | 200 +++ 17 files changed, 1128 insertions(+), 1152 deletions(-) create mode 100644 connectors/vmware/lib/command-cpuhost.pm create mode 100644 connectors/vmware/lib/command-datastoreio.pm create mode 100644 connectors/vmware/lib/command-datastoreshost.pm create mode 100644 connectors/vmware/lib/command-datastoreusage.pm create mode 100644 connectors/vmware/lib/command-getmap.pm create mode 100644 connectors/vmware/lib/command-healthhost.pm create mode 100644 connectors/vmware/lib/command-listdatastore.pm create mode 100644 connectors/vmware/lib/command-listhost.pm create mode 100644 connectors/vmware/lib/command-listnichost.pm create mode 100644 connectors/vmware/lib/command-maintenancehost.pm create mode 100644 connectors/vmware/lib/command-memhost.pm create mode 100644 connectors/vmware/lib/command-nethost.pm create mode 100644 connectors/vmware/lib/command-statushost.pm create mode 100644 connectors/vmware/lib/command-swaphost.pm create mode 100644 connectors/vmware/lib/esxd-common.pm diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index e5f9704a6..ee6483425 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -20,7 +20,7 @@ use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; -use vars qw($port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); +use vars qw($libpath $port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); use vars qw($LOG $log_mode $log_crit $log_facility); use constant { LOG_ESXD_ERROR => 1, @@ -28,6 +28,21 @@ use constant { }; require '/etc/centreon/centreon_esxd.pm'; +require $libpath . '/esxd-common.pm'; +require $libpath . '/command-cpuhost.pm'; +require $libpath . '/command-datastoreio.pm'; +require $libpath . '/command-datastoreshost.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-nethost.pm'; +require $libpath . '/command-statushost.pm'; +require $libpath . '/command-swaphost.pm'; our $session_id; our %sockets = (); @@ -74,1157 +89,6 @@ our %checks_descr = ( "getmap" => {'arg' => \&getmap_check_args, 'compute' => \&getmap_compute_args, 'exec' => \&getmap_do} ); -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 LOG_ERR, $_[1] if ($_[0] == LOG_ESXD_ERROR); - syslog LOG_INFO, $_[1] if ($_[0] == LOG_ESXD_INFO); - } -} - -sub connect_vsphere { - writeLogFile(LOG_ESXD_INFO, "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, "No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/); - writeLogFile(LOG_ESXD_ERROR, "You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/); - writeLogFile(LOG_ESXD_ERROR, "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, "$@"); - 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 (@t) = gmtime(time() - $interval); - my $start = sprintf("%04d-%02d-%02dT%02d:%02d:00Z", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1]); - my $perf_query_spec = PerfQuerySpec->new(entity => $view, - metricId => @perf_metric_ids, - format => 'normal', - intervalId => $interval, - startTime => $start - ); - #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, "$@"); - 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; - } - } - }; - if ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); - 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 ($@ =~ /decryption failed or bad record mac/) { - writeLogFile(LOG_ESXD_ERROR, "$@"); - eval { - $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); - }; - if ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); - my $lerror = $@; - $lerror =~ s/\n/ /g; - print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); - return undef; - } - } elsif ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); - my $lerror = $@; - $lerror =~ s/\n/ /g; - print_response("-1|Error: " . $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; -} - -############## -# Health Function -############## - -sub healthhost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub healthhost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub healthhost_do { - my ($lhost) = @_; - - my %filters = ('name' => $lhost); - my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output_critical = ''; - my $output_critical_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output = ''; - my $output_append = ''; - my $OKCount = 0; - my $CAlertCount = 0; - my $WAlertCount = 0; - foreach my $entity_view (@$result) { - my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo'}; - my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; - if (!defined($cpuStatusInfo)) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - output_add(\$output_critical, \$output_critical_append, ", ", - "API error - unable to get cpuStatusInfo"); - } - if (!defined($numericSensorInfo)) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - output_add(\$output_critical, \$output_critical_append, ", ", - "API error - unable to get numericSensorInfo"); - } - - # CPU - foreach (@$cpuStatusInfo) { - if ($_->status->key =~ /^red$/i) { - output_add(\$output_critical, \$output_critical_append, ", ", - $_->name . ": " . $_->status->summary); - $status |= $MYERRORS_MASK{'CRITICAL'}; - $CAlertCount++; - } elsif ($_->status->key =~ /^yellow$/i) { - output_add(\$output_warning, \$output_warning_append, ", ", - $_->name . ": " . $_->status->summary); - $status |= $MYERRORS_MASK{'WARNING'}; - $WAlertCount++; - } else { - $OKCount++; - } - } - # Sensor - foreach (@$numericSensorInfo) { - if ($_->healthState->key =~ /^red$/i) { - output_add(\$output_critical, \$output_critical_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status |= $MYERRORS_MASK{'CRITICAL'}; - $CAlertCount++; - } elsif ($_->healthState->key =~ /^yellow$/i) { - output_add(\$output_warning, \$output_warning_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status |= $MYERRORS_MASK{'WARNING'}; - $WAlertCount++; - } else { - $OKCount++; - } - } - } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $CAlertCount health issue(s) found: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $WAlertCount health issue(s) found: $output_warning"; - } - if ($status == 0) { - $output = "All $OKCount health checks are green"; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# DatastoreUsage Function -############ - -sub datastoreusage_check_args { - my ($ds, $warn, $crit) = @_; - if (!defined($ds) || $ds eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoreusage_compute_args { - my $ds = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($ds, $warn, $crit); -} - -sub datastoreusage_do { - my ($ds, $warn, $crit) = @_; - my %filters = ('summary.name' => $ds); - my @properties = ('summary'); - - my $result = get_entities_host('Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ""; - if ($$result[0]->summary->accessible == 1) { - my $dsName = $$result[0]->summary->name; - my $capacity = $$result[0]->summary->capacity; - my $free = $$result[0]->summary->freeSpace; - my $pct = ($capacity - $free) / $capacity * 100; - - my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; - my $sizeD = $capacity / 1024 / 1024 / 1024; - - $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; - if ($pct >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($pct > $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - } else { - $output = "Datastore '$ds' summary not accessible."; - $status |= $MYERRORS_MASK{'UNKNOWN'}; - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# DatastoreIO Func -############ - -sub datastoreio_check_args { - my ($ds, $warn, $crit) = @_; - if (!defined($ds) || $ds eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoreio_compute_args { - my $ds = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : ''); - my $crit = (defined($_[2]) ? $_[2] : ''); - return ($ds, $warn, $crit); -} - -sub datastoreio_do { - my ($ds, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('summary.name' => $ds); - my @properties = ('summary.name'); - my $result = get_entities_host('Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'datastore.read.average', 'instances' => ['']}, - {'label' => 'datastore.write.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.read.average'}->{'key'} . ":"}[0])); - my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.write.average'}->{'key'} . ":"}[0])); - - my $status = 0; # OK - my $output = ''; - - if ((defined($warn) && $warn ne "") && ($read_counter >= $warn || $write_counter >= $warn)) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ((defined($crit) && $crit ne "") && ($read_counter >= $crit || $write_counter >= $crit)) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Rate of reading data : " . simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . simplify_number($write_counter / 1024 * 8) . " Mb/s"; - $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# Maintenance Func -############ - -sub maintenancehost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub maintenancehost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub maintenancehost_do { - my ($lhost) = @_; - my %filters = ('name' => $lhost); - my @properties = ('runtime.inMaintenanceMode'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - - foreach my $entity_view (@$result) { - if ($entity_view->{'runtime.inMaintenanceMode'} ne "false") { - $status |= $MYERRORS_MASK{'CRITICAL'}; - $output = "Server $lhost is on maintenance mode."; - } else { - $output = "Server $lhost is not on maintenance mode."; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# Status Func -############ - -sub statushost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub statushost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub statushost_do { - my ($lhost) = @_; - my %filters = ('name' => $lhost); - my @properties = ('summary.overallStatus'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - - my %overallStatus = ( - 'gray' => 'status is unknown', - 'green' => 'is OK', - 'red' => 'has a problem', - 'yellow' => 'might have a problem', - ); - my %overallStatusReturn = ( - 'gray' => 'UNKNOWN', - 'green' => 'OK', - 'red' => 'CRITICAL', - 'yellow' => 'WARNING' - ); - - foreach my $entity_view (@$result) { - my $status = $entity_view->{'summary.overallStatus'}->val; - - if (defined($status) && $overallStatus{$status}) { - $output = "The Server '$lhost' " . $overallStatus{$status}; - if ($MYERRORS_MASK{$overallStatusReturn{$status}} != 0) { - $status |= $MYERRORS_MASK{$overallStatusReturn{$status}}; - } - } else { - $output = "Can't interpret data..."; - $status |= $MYERRORS_MASK{'UNKNOWN'}; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# CPUHost Func -############ - -sub cpuhost_check_args { - my ($host, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub cpuhost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($lhost, $warn, $crit); -} - -sub cpuhost_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('hardware.cpuInfo.numCpuThreads'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @instances = ('*'); - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'cpu.usage.average', 'instances' => \@instances}], - $perfcounter_speriod); - - my $status = 0; # OK - my $output = ''; - my $total_cpu_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - - if ($total_cpu_average >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($total_cpu_average >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Total Average CPU usage '$total_cpu_average%' on last " . ($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100"; - - foreach my $id (sort { my ($cida, $cia) = split /:/, $a; - my ($cidb, $cib) = split /:/, $b; - $cia = -1 if (!defined($cia) || $cia eq ""); - $cib = -1 if (!defined($cib) || $cib eq ""); - $cia <=> $cib} keys %$values) { - my ($counter_id, $instance) = split /:/, $id; - if ($instance ne "") { - $output .= " cpu$instance=" . simplify_number(convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; - } - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# NetHost Func -############ - -sub nethost_check_args { - my ($host, $pnic, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (!defined($pnic) || $pnic eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need physical nic name\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub nethost_compute_args { - my $lhost = $_[0]; - my $pnic = $_[1]; - my $warn = (defined($_[2]) ? $_[2] : 80); - my $crit = (defined($_[3]) ? $_[3] : 90); - return ($lhost, $pnic, $warn, $crit); -} - -sub nethost_do { - my ($lhost, $pnic, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('config.network.pnic'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - my %pnic_def = (); - foreach (@{$$result[0]->{'config.network.pnic'}}) { - if (defined($_->linkSpeed)) { - $pnic_def{$_->device} = $_->linkSpeed->speedMb; - } - } - - if (!defined($pnic_def{$pnic})) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Link '$pnic' not exist or down.\n"; - return ; - } - - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'net.received.average', 'instances' => [$pnic]}, - {'label' => 'net.transmitted.average', 'instances' => [$pnic]}], - $perfcounter_speriod); - - my $traffic_in = simplify_number(convert_number($values->{$perfcounter_cache{'net.received.average'}->{'key'} . ":" . $pnic}[0])); - my $traffic_out = simplify_number(convert_number($values->{$perfcounter_cache{'net.transmitted.average'}->{'key'} . ":" . $pnic}[0])); - my $status = 0; # OK - my $output = ''; - - if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Traffic In : " . simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %), Out : " . simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %)"; - $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# DiskHost Func -############ - -sub datastoreshost_check_args { - my ($lhost, $warn, $crit) = @_; - if (!defined($lhost) || $lhost eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoreshost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : ''); - my $crit = (defined($_[2]) ? $_[2] : ''); - return ($lhost, $warn, $crit); -} - -sub datastoreshost_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('config.fileSystemVolume.mountInfo'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my %uuid_list = (); - my %disk_name = (); - foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { - if ($_->volume->isa('HostVmfsVolume')) { - $uuid_list{$_->volume->uuid} = $_->volume->name; - # Not need. We are on Datastore level (not LUN level) - #foreach my $extent (@{$_->volume->extent}) { - # $disk_name{$extent->diskName} = $_->volume->name; - #} - } - if ($_->volume->isa('HostNasVolume')) { - $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; - } - } - - # Vsphere >= 4.1 - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, - {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], - $perfcounter_speriod); - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $perfdata = ''; - foreach (keys %uuid_list) { - if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and - defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { - my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); - my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); - if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - - $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; - } - } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Latency counter: $output_warning"; - } - if ($status == 0) { - $output = "All Datastore latency counters are ok"; - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); -} - - -############ -# MemHost Func -############ - -sub memhost_check_args { - my ($host, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub memhost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($lhost, $warn, $crit); -} - -sub memhost_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('summary.hardware.memorySize'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; - - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'mem.consumed.average', 'instances' => ['']}, - {'label' => 'mem.overhead.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $mem_used = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); - my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if ($mem_used * 100 / ($memory_size / 1024) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($mem_used * 100 / ($memory_size / 1024) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Memory used : " . simplify_number($mem_used / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; - $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# SwapHost Func -############ - -sub swaphost_check_args { - my ($host, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub swaphost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 0.8); - my $crit = (defined($_[2]) ? $_[2] : 1); - return ($lhost, $warn, $crit); -} - -sub swaphost_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - #my @properties = ('summary'); - my @properties = (); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, - {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $swap_in = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapinRate.average'}->{'key'} . ":"}[0])); - my $swap_out = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if (($swap_in / 1024) >= $warn || ($swap_out / 1024) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (($swap_in / 1024) >= $crit || ($swap_out / 1024) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; - $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - - -############ -# List Host Func -############ - -sub listhost_check_args { - return 0; -} - -sub listhost_compute_args { - return undef; -} - -sub listhost_do { - my %filters = (); - my @properties = ('name'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Host List: '; - my $output_append = ""; - - foreach my $entity_view (@$result) { - $output .= $output_append . $entity_view->{name}; - $output_append = ', '; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# List Datastore Func -############ - -sub listdatastore_check_args { - return 0; -} - -sub listdatastore_compute_args { - return undef; -} - -sub listdatastore_do { - my ($ds, $warn, $crit) = @_; - my %filters = (); - my @properties = ('datastore'); - - my $result = get_entities_host('Datacenter', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @ds_array = (); - foreach my $entity_view (@$result) { - if (defined $entity_view->datastore) { - @ds_array = (@ds_array, @{$entity_view->datastore}); - } - } - - @properties = ('summary'); - $result = get_views(\@ds_array, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Datastore List: '; - my $output_append = ""; - foreach my $datastore (@$result) { - if ($datastore->summary->accessible) { - $output .= $output_append . "'" . $datastore->summary->name . "'"; - $output_append = ', '; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ -# List Host Func -############ - -sub listnichost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub listnichost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub listnichost_do { - my ($lhost) = @_; - my %filters = ('name' => $lhost); - my @properties = ('config.network.pnic'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output_up = 'Nic Up List: '; - my $output_down = 'Nic Down List: '; - my $output_up_append = ""; - my $output_down_append = ""; - foreach (@{$$result[0]->{'config.network.pnic'}}) { - if (defined($_->linkSpeed)) { - $output_up .= $output_up_append . "'" . $_->device . "'"; - $output_up_append = ', '; - } else { - $output_down .= $output_down_append . "'" . $_->device . "'"; - $output_down_append = ', '; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"); -} - -############ -# Get Map Func -############ - -sub getmap_check_args { - return 0; -} - -sub getmap_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub getmap_do { - my ($lhost) = @_; - my %filters = (); - if (defined($lhost) and $lhost ne "") { - %filters = ('name' => $lhost); - } - my @properties = ('name', 'vm'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - my $output_append = ""; - - foreach my $entity_view (@$result) { - $output .= $output_append . "ESX Host '" . $entity_view->name . "': "; - my @vm_array = (); - if (defined $entity_view->vm) { - @vm_array = (@vm_array, @{$entity_view->vm}); - } - - @properties = ('name', 'summary.runtime.powerState'); - my $result2 = get_views(\@vm_array, \@properties); - if (!defined($result)) { - return ; - } - - my $output_append2 = ''; - foreach my $vm (@$result2) { - if ($vm->{'summary.runtime.powerState'}->val eq "poweredOn") { - $output .= $output_append2 . "[" . $vm->name . "]"; - $output_append2 = ', '; - } - } - $output_append = ". "; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -############ - sub catch_zap_term { writeLogFile(LOG_ESXD_INFO, "$$ Receiving order to stop...\n"); $stop = 1; diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index 4b613d4e2..64942f13d 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -1,3 +1,5 @@ + +our $libpath = '/usr/share/centreon/lib/centreon-esxd'; our $port = 5700; our $service_url = "https://XXXX.XXXX.XXX/sdk"; our $username = "xxxxx"; diff --git a/connectors/vmware/lib/command-cpuhost.pm b/connectors/vmware/lib/command-cpuhost.pm new file mode 100644 index 000000000..17da75302 --- /dev/null +++ b/connectors/vmware/lib/command-cpuhost.pm @@ -0,0 +1,76 @@ +sub cpuhost_check_args { + my ($host, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub cpuhost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($lhost, $warn, $crit); +} + +sub cpuhost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('hardware.cpuInfo.numCpuThreads'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @instances = ('*'); + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'cpu.usage.average', 'instances' => \@instances}], + $perfcounter_speriod); + + my $status = 0; # OK + my $output = ''; + my $total_cpu_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + + if ($total_cpu_average >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($total_cpu_average >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Total Average CPU usage '$total_cpu_average%' on last " . ($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100"; + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %$values) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "") { + $output .= " cpu$instance=" . simplify_number(convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; + } + } + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-datastoreio.pm b/connectors/vmware/lib/command-datastoreio.pm new file mode 100644 index 000000000..01621e955 --- /dev/null +++ b/connectors/vmware/lib/command-datastoreio.pm @@ -0,0 +1,68 @@ +sub datastoreio_check_args { + my ($ds, $warn, $crit) = @_; + if (!defined($ds) || $ds eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub datastoreio_compute_args { + my $ds = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : ''); + my $crit = (defined($_[2]) ? $_[2] : ''); + return ($ds, $warn, $crit); +} + +sub datastoreio_do { + my ($ds, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('summary.name' => $ds); + my @properties = ('summary.name'); + my $result = get_entities_host('Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'datastore.read.average', 'instances' => ['']}, + {'label' => 'datastore.write.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.read.average'}->{'key'} . ":"}[0])); + my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.write.average'}->{'key'} . ":"}[0])); + + my $status = 0; # OK + my $output = ''; + + if ((defined($warn) && $warn ne "") && ($read_counter >= $warn || $write_counter >= $warn)) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ((defined($crit) && $crit ne "") && ($read_counter >= $crit || $write_counter >= $crit)) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Rate of reading data : " . simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . simplify_number($write_counter / 1024 * 8) . " Mb/s"; + $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-datastoreshost.pm b/connectors/vmware/lib/command-datastoreshost.pm new file mode 100644 index 000000000..b230422ae --- /dev/null +++ b/connectors/vmware/lib/command-datastoreshost.pm @@ -0,0 +1,114 @@ +sub datastoreshost_check_args { + my ($lhost, $warn, $crit) = @_; + if (!defined($lhost) || $lhost eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub datastoreshost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : ''); + my $crit = (defined($_[2]) ? $_[2] : ''); + return ($lhost, $warn, $crit); +} + +sub datastoreshost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('config.fileSystemVolume.mountInfo'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my %uuid_list = (); + my %disk_name = (); + foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { + if ($_->volume->isa('HostVmfsVolume')) { + $uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + #foreach my $extent (@{$_->volume->extent}) { + # $disk_name{$extent->diskName} = $_->volume->name; + #} + } + if ($_->volume->isa('HostNasVolume')) { + $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; + } + } + + # Vsphere >= 4.1 + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, + {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], + $perfcounter_speriod); + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $perfdata = ''; + foreach (keys %uuid_list) { + if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and + defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { + my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); + my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); + if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + + $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; + } + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Latency counter: $output_warning"; + } + if ($status == 0) { + $output = "All Datastore latency counters are ok"; + } + print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); +} + +1; diff --git a/connectors/vmware/lib/command-datastoreusage.pm b/connectors/vmware/lib/command-datastoreusage.pm new file mode 100644 index 000000000..5b4c3a176 --- /dev/null +++ b/connectors/vmware/lib/command-datastoreusage.pm @@ -0,0 +1,64 @@ +sub datastoreusage_check_args { + my ($ds, $warn, $crit) = @_; + if (!defined($ds) || $ds eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub datastoreusage_compute_args { + my $ds = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($ds, $warn, $crit); +} + +sub datastoreusage_do { + my ($ds, $warn, $crit) = @_; + my %filters = ('summary.name' => $ds); + my @properties = ('summary'); + + my $result = get_entities_host('Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ""; + if ($$result[0]->summary->accessible == 1) { + my $dsName = $$result[0]->summary->name; + my $capacity = $$result[0]->summary->capacity; + my $free = $$result[0]->summary->freeSpace; + my $pct = ($capacity - $free) / $capacity * 100; + + my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; + my $sizeD = $capacity / 1024 / 1024 / 1024; + + $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; + if ($pct >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($pct > $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + } else { + $output = "Datastore '$ds' summary not accessible."; + $status |= $MYERRORS_MASK{'UNKNOWN'}; + } + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-getmap.pm b/connectors/vmware/lib/command-getmap.pm new file mode 100644 index 000000000..70bd115f8 --- /dev/null +++ b/connectors/vmware/lib/command-getmap.pm @@ -0,0 +1,53 @@ + +sub getmap_check_args { + return 0; +} + +sub getmap_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub getmap_do { + my ($lhost) = @_; + my %filters = (); + if (defined($lhost) and $lhost ne "") { + %filters = ('name' => $lhost); + } + my @properties = ('name', 'vm'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + my $output_append = ""; + + foreach my $entity_view (@$result) { + $output .= $output_append . "ESX Host '" . $entity_view->name . "': "; + my @vm_array = (); + if (defined $entity_view->vm) { + @vm_array = (@vm_array, @{$entity_view->vm}); + } + + @properties = ('name', 'summary.runtime.powerState'); + my $result2 = get_views(\@vm_array, \@properties); + if (!defined($result)) { + return ; + } + + my $output_append2 = ''; + foreach my $vm (@$result2) { + if ($vm->{'summary.runtime.powerState'}->val eq "poweredOn") { + $output .= $output_append2 . "[" . $vm->name . "]"; + $output_append2 = ', '; + } + } + $output_append = ". "; + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-healthhost.pm b/connectors/vmware/lib/command-healthhost.pm new file mode 100644 index 000000000..497781a91 --- /dev/null +++ b/connectors/vmware/lib/command-healthhost.pm @@ -0,0 +1,97 @@ +sub healthhost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub healthhost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub healthhost_do { + my ($lhost) = @_; + + my %filters = ('name' => $lhost); + my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output_critical = ''; + my $output_critical_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output = ''; + my $output_append = ''; + my $OKCount = 0; + my $CAlertCount = 0; + my $WAlertCount = 0; + foreach my $entity_view (@$result) { + my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo'}; + my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; + if (!defined($cpuStatusInfo)) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + output_add(\$output_critical, \$output_critical_append, ", ", + "API error - unable to get cpuStatusInfo"); + } + if (!defined($numericSensorInfo)) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + output_add(\$output_critical, \$output_critical_append, ", ", + "API error - unable to get numericSensorInfo"); + } + + # CPU + foreach (@$cpuStatusInfo) { + if ($_->status->key =~ /^red$/i) { + output_add(\$output_critical, \$output_critical_append, ", ", + $_->name . ": " . $_->status->summary); + $status |= $MYERRORS_MASK{'CRITICAL'}; + $CAlertCount++; + } elsif ($_->status->key =~ /^yellow$/i) { + output_add(\$output_warning, \$output_warning_append, ", ", + $_->name . ": " . $_->status->summary); + $status |= $MYERRORS_MASK{'WARNING'}; + $WAlertCount++; + } else { + $OKCount++; + } + } + # Sensor + foreach (@$numericSensorInfo) { + if ($_->healthState->key =~ /^red$/i) { + output_add(\$output_critical, \$output_critical_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status |= $MYERRORS_MASK{'CRITICAL'}; + $CAlertCount++; + } elsif ($_->healthState->key =~ /^yellow$/i) { + output_add(\$output_warning, \$output_warning_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status |= $MYERRORS_MASK{'WARNING'}; + $WAlertCount++; + } else { + $OKCount++; + } + } + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - $CAlertCount health issue(s) found: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - $WAlertCount health issue(s) found: $output_warning"; + } + if ($status == 0) { + $output = "All $OKCount health checks are green"; + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-listdatastore.pm b/connectors/vmware/lib/command-listdatastore.pm new file mode 100644 index 000000000..449a5b5ef --- /dev/null +++ b/connectors/vmware/lib/command-listdatastore.pm @@ -0,0 +1,45 @@ +sub listdatastore_check_args { + return 0; +} + +sub listdatastore_compute_args { + return undef; +} + +sub listdatastore_do { + my ($ds, $warn, $crit) = @_; + my %filters = (); + my @properties = ('datastore'); + + my $result = get_entities_host('Datacenter', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @ds_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->datastore) { + @ds_array = (@ds_array, @{$entity_view->datastore}); + } + } + + @properties = ('summary'); + $result = get_views(\@ds_array, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Datastore List: '; + my $output_append = ""; + foreach my $datastore (@$result) { + if ($datastore->summary->accessible) { + $output .= $output_append . "'" . $datastore->summary->name . "'"; + $output_append = ', '; + } + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-listhost.pm b/connectors/vmware/lib/command-listhost.pm new file mode 100644 index 000000000..30769a05b --- /dev/null +++ b/connectors/vmware/lib/command-listhost.pm @@ -0,0 +1,30 @@ + +sub listhost_check_args { + return 0; +} + +sub listhost_compute_args { + return undef; +} + +sub listhost_do { + my %filters = (); + my @properties = ('name'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Host List: '; + my $output_append = ""; + + foreach my $entity_view (@$result) { + $output .= $output_append . $entity_view->{name}; + $output_append = ', '; + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-listnichost.pm b/connectors/vmware/lib/command-listnichost.pm new file mode 100644 index 000000000..03ad23bc0 --- /dev/null +++ b/connectors/vmware/lib/command-listnichost.pm @@ -0,0 +1,43 @@ + +sub listnichost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub listnichost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub listnichost_do { + my ($lhost) = @_; + my %filters = ('name' => $lhost); + my @properties = ('config.network.pnic'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output_up = 'Nic Up List: '; + my $output_down = 'Nic Down List: '; + my $output_up_append = ""; + my $output_down_append = ""; + foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($_->linkSpeed)) { + $output_up .= $output_up_append . "'" . $_->device . "'"; + $output_up_append = ', '; + } else { + $output_down .= $output_down_append . "'" . $_->device . "'"; + $output_down_append = ', '; + } + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"); +} + +1; diff --git a/connectors/vmware/lib/command-maintenancehost.pm b/connectors/vmware/lib/command-maintenancehost.pm new file mode 100644 index 000000000..b02f96e9a --- /dev/null +++ b/connectors/vmware/lib/command-maintenancehost.pm @@ -0,0 +1,39 @@ +sub maintenancehost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub maintenancehost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub maintenancehost_do { + my ($lhost) = @_; + my %filters = ('name' => $lhost); + my @properties = ('runtime.inMaintenanceMode'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + foreach my $entity_view (@$result) { + if ($entity_view->{'runtime.inMaintenanceMode'} ne "false") { + $status |= $MYERRORS_MASK{'CRITICAL'}; + $output = "Server $lhost is on maintenance mode."; + } else { + $output = "Server $lhost is not on maintenance mode."; + } + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-memhost.pm b/connectors/vmware/lib/command-memhost.pm new file mode 100644 index 000000000..b57494a93 --- /dev/null +++ b/connectors/vmware/lib/command-memhost.pm @@ -0,0 +1,70 @@ +sub memhost_check_args { + my ($host, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub memhost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($lhost, $warn, $crit); +} + +sub memhost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('summary.hardware.memorySize'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; + + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'mem.consumed.average', 'instances' => ['']}, + {'label' => 'mem.overhead.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $mem_used = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); + my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if ($mem_used * 100 / ($memory_size / 1024) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($mem_used * 100 / ($memory_size / 1024) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Memory used : " . simplify_number($mem_used / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; + $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-nethost.pm b/connectors/vmware/lib/command-nethost.pm new file mode 100644 index 000000000..bb230fd51 --- /dev/null +++ b/connectors/vmware/lib/command-nethost.pm @@ -0,0 +1,86 @@ + +sub nethost_check_args { + my ($host, $pnic, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + if (!defined($pnic) || $pnic eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need physical nic name\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub nethost_compute_args { + my $lhost = $_[0]; + my $pnic = $_[1]; + my $warn = (defined($_[2]) ? $_[2] : 80); + my $crit = (defined($_[3]) ? $_[3] : 90); + return ($lhost, $pnic, $warn, $crit); +} + +sub nethost_do { + my ($lhost, $pnic, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('config.network.pnic'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + my %pnic_def = (); + foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($_->linkSpeed)) { + $pnic_def{$_->device} = $_->linkSpeed->speedMb; + } + } + + if (!defined($pnic_def{$pnic})) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print $ERRORS{$MYERRORS{$status}} . "|Link '$pnic' not exist or down.\n"; + return ; + } + + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'net.received.average', 'instances' => [$pnic]}, + {'label' => 'net.transmitted.average', 'instances' => [$pnic]}], + $perfcounter_speriod); + + my $traffic_in = simplify_number(convert_number($values->{$perfcounter_cache{'net.received.average'}->{'key'} . ":" . $pnic}[0])); + my $traffic_out = simplify_number(convert_number($values->{$perfcounter_cache{'net.transmitted.average'}->{'key'} . ":" . $pnic}[0])); + my $status = 0; # OK + my $output = ''; + + if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Traffic In : " . simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %), Out : " . simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %)"; + $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-statushost.pm b/connectors/vmware/lib/command-statushost.pm new file mode 100644 index 000000000..eac151302 --- /dev/null +++ b/connectors/vmware/lib/command-statushost.pm @@ -0,0 +1,57 @@ +sub statushost_check_args { + my ($host) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + return 0; +} + +sub statushost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub statushost_do { + my ($lhost) = @_; + my %filters = ('name' => $lhost); + my @properties = ('summary.overallStatus'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + my %overallStatus = ( + 'gray' => 'status is unknown', + 'green' => 'is OK', + 'red' => 'has a problem', + 'yellow' => 'might have a problem', + ); + my %overallStatusReturn = ( + 'gray' => 'UNKNOWN', + 'green' => 'OK', + 'red' => 'CRITICAL', + 'yellow' => 'WARNING' + ); + + foreach my $entity_view (@$result) { + my $status = $entity_view->{'summary.overallStatus'}->val; + + if (defined($status) && $overallStatus{$status}) { + $output = "The Server '$lhost' " . $overallStatus{$status}; + if ($MYERRORS_MASK{$overallStatusReturn{$status}} != 0) { + $status |= $MYERRORS_MASK{$overallStatusReturn{$status}}; + } + } else { + $output = "Can't interpret data..."; + $status |= $MYERRORS_MASK{'UNKNOWN'}; + } + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-swaphost.pm b/connectors/vmware/lib/command-swaphost.pm new file mode 100644 index 000000000..31bfc5bb0 --- /dev/null +++ b/connectors/vmware/lib/command-swaphost.pm @@ -0,0 +1,68 @@ +sub swaphost_check_args { + my ($host, $warn, $crit) = @_; + if (!defined($host) || $host eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub swaphost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 0.8); + my $crit = (defined($_[2]) ? $_[2] : 1); + return ($lhost, $warn, $crit); +} + +sub swaphost_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + #my @properties = ('summary'); + my @properties = (); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, + {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $swap_in = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapinRate.average'}->{'key'} . ":"}[0])); + my $swap_out = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if (($swap_in / 1024) >= $warn || ($swap_out / 1024) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (($swap_in / 1024) >= $crit || ($swap_out / 1024) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; + $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm new file mode 100644 index 000000000..8d9a23c0b --- /dev/null +++ b/connectors/vmware/lib/esxd-common.pm @@ -0,0 +1,200 @@ +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 LOG_ERR, $_[1] if ($_[0] == LOG_ESXD_ERROR); + syslog LOG_INFO, $_[1] if ($_[0] == LOG_ESXD_INFO); + } +} + +sub connect_vsphere { + writeLogFile(LOG_ESXD_INFO, "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, "No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/); + writeLogFile(LOG_ESXD_ERROR, "You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/); + writeLogFile(LOG_ESXD_ERROR, "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, "$@"); + 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 (@t) = gmtime(time() - $interval); + my $start = sprintf("%04d-%02d-%02dT%02d:%02d:00Z", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1]); + my $perf_query_spec = PerfQuerySpec->new(entity => $view, + metricId => @perf_metric_ids, + format => 'normal', + intervalId => $interval, + startTime => $start + ); + #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, "$@"); + 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; + } + } + }; + if ($@) { + writeLogFile(LOG_ESXD_ERROR, "$@"); + 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 ($@ =~ /decryption failed or bad record mac/) { + writeLogFile(LOG_ESXD_ERROR, "$@"); + eval { + $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + }; + if ($@) { + writeLogFile(LOG_ESXD_ERROR, "$@"); + my $lerror = $@; + $lerror =~ s/\n/ /g; + print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); + return undef; + } + } elsif ($@) { + writeLogFile(LOG_ESXD_ERROR, "$@"); + my $lerror = $@; + $lerror =~ s/\n/ /g; + print_response("-1|Error: " . $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; +} + +1; From bfb5688ddb1ea96535581095f05e26b609582bef Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 20 Sep 2012 15:21:45 +0000 Subject: [PATCH 009/447] Evolution #3966 [vm] CPU check git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@16 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 27 +++++++- connectors/vmware/centreon_esxd | 2 + connectors/vmware/lib/command-cpuhost.pm | 2 +- connectors/vmware/lib/command-cpuvm.pm | 79 ++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 connectors/vmware/lib/command-cpuvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 603e6ed9b..e35f4dd0f 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -34,6 +34,7 @@ GetOptions( "u|usage=s" => \$OPTION{'usage'}, "e|esx-host=s" => \$OPTION{'esx-host'}, + "vm=s" => \$OPTION{'vm'}, "datastore=s" => \$OPTION{'datastore'}, "nic=s" => \$OPTION{'nic'}, @@ -110,6 +111,11 @@ sub print_usage () { print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; print "\n"; + print "'cpuvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -330,6 +336,25 @@ sub nethost_get_str { return "nethost|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub cpuvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub cpuvm_get_str { + return "cpuvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + sub listhost_check_arg { return 0; } @@ -384,7 +409,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|listhost|listdatastore|listnichost|getmap)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index ee6483425..95e60f9a8 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -30,6 +30,7 @@ use constant { require '/etc/centreon/centreon_esxd.pm'; require $libpath . '/esxd-common.pm'; require $libpath . '/command-cpuhost.pm'; +require $libpath . '/command-cpuvm.pm'; require $libpath . '/command-datastoreio.pm'; require $libpath . '/command-datastoreshost.pm'; require $libpath . '/command-datastoreusage.pm'; @@ -83,6 +84,7 @@ our %checks_descr = ( "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}, + "cpuvm" => {'arg' => \&cpuvm_check_args, 'compute' => \&cpuvm_compute_args, 'exec' => \&cpuvm_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}, diff --git a/connectors/vmware/lib/command-cpuhost.pm b/connectors/vmware/lib/command-cpuhost.pm index 17da75302..5aae3ec62 100644 --- a/connectors/vmware/lib/command-cpuhost.pm +++ b/connectors/vmware/lib/command-cpuhost.pm @@ -35,7 +35,7 @@ sub cpuhost_do { } my %filters = ('name' => $lhost); - my @properties = ('hardware.cpuInfo.numCpuThreads'); + my @properties = ('name'); my $result = get_entities_host('HostSystem', \%filters, \@properties); if (!defined($result)) { return ; diff --git a/connectors/vmware/lib/command-cpuvm.pm b/connectors/vmware/lib/command-cpuvm.pm new file mode 100644 index 000000000..d8eda8544 --- /dev/null +++ b/connectors/vmware/lib/command-cpuvm.pm @@ -0,0 +1,79 @@ + +sub cpuvm_check_args { + my ($vm, $warn, $crit) = @_; + if (!defined($vm) || $vm eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm hostname\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub cpuvm_compute_args { + my $lvm = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($lvm, $warn, $crit); +} + +sub cpuvm_do { + my ($lvm, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lvm); + my @properties = ('name'); + my $result = get_entities_host('VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @instances = ('*'); + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'cpu.usage.average', 'instances' => \@instances}, + {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], + $perfcounter_speriod); + + my $status = 0; # OK + my $output = ''; + my $total_cpu_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + + if ($total_cpu_average >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($total_cpu_average >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . ($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %$values) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "") { + $output .= " cpu" . $instance . "_MHz=" . simplify_number(convert_number($values->{$id}[0])) . "MHz"; + } + } + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; From 1d139af98d7f3438acde031456a9bb4ec7616d77 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 20 Sep 2012 15:34:39 +0000 Subject: [PATCH 010/447] =?UTF-8?q?Evolution=20#3993=20Modifier=20la=20fa?= =?UTF-8?q?=C3=A7on=20de=20r=C3=A9cup=C3=A9rer=20les=20datastores=20avec?= =?UTF-8?q?=20listdatastore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@17 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/command-datastoreusage.pm | 2 +- connectors/vmware/lib/command-listdatastore.pm | 17 ++--------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/connectors/vmware/lib/command-datastoreusage.pm b/connectors/vmware/lib/command-datastoreusage.pm index 5b4c3a176..1d5606ca6 100644 --- a/connectors/vmware/lib/command-datastoreusage.pm +++ b/connectors/vmware/lib/command-datastoreusage.pm @@ -28,7 +28,7 @@ sub datastoreusage_compute_args { sub datastoreusage_do { my ($ds, $warn, $crit) = @_; - my %filters = ('summary.name' => $ds); + my %filters = ('name' => $ds); my @properties = ('summary'); my $result = get_entities_host('Datastore', \%filters, \@properties); diff --git a/connectors/vmware/lib/command-listdatastore.pm b/connectors/vmware/lib/command-listdatastore.pm index 449a5b5ef..fdd4773ac 100644 --- a/connectors/vmware/lib/command-listdatastore.pm +++ b/connectors/vmware/lib/command-listdatastore.pm @@ -9,22 +9,9 @@ sub listdatastore_compute_args { sub listdatastore_do { my ($ds, $warn, $crit) = @_; my %filters = (); - my @properties = ('datastore'); + my @properties = ('summary'); - my $result = get_entities_host('Datacenter', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @ds_array = (); - foreach my $entity_view (@$result) { - if (defined $entity_view->datastore) { - @ds_array = (@ds_array, @{$entity_view->datastore}); - } - } - - @properties = ('summary'); - $result = get_views(\@ds_array, \@properties); + my $result = get_entities_host('Datastore', \%filters, \@properties); if (!defined($result)) { return ; } From 1a7c914784d0e53ef25dd93a450805d1cf914e66 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 21 Sep 2012 09:40:06 +0000 Subject: [PATCH 011/447] Fix when syslog not installed git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@18 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 14 +++++++++++++- connectors/vmware/lib/esxd-common.pm | 4 ++-- connectors/vmware/lib/esxd-syslog.pm | 6 ++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 connectors/vmware/lib/esxd-syslog.pm diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 95e60f9a8..c186944e0 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -3,8 +3,10 @@ BEGIN { $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)); } @@ -22,6 +24,8 @@ use Data::Dumper; use vars qw($libpath $port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); use vars qw($LOG $log_mode $log_crit $log_facility); +use vars qw($openlog_option $syslog_err_priority $syslog_info_priority); + use constant { LOG_ESXD_ERROR => 1, LOG_ESXD_INFO => 2 @@ -70,6 +74,14 @@ our $session1; our $counter = 0; our $global_id; +our $openlog_option; +our $syslog_err_priority; +our $syslog_info_priority; + +if ($ENV{ESX_SYSLOGD_LOAD} == 1) { + require $libpath . '/esxd-syslog.pm'; +} + 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); @@ -283,7 +295,7 @@ if ($log_mode == 1) { open STDERR, '>&', $centesx_fh; } if ($log_mode == 2) { - openlog $0, LOG_PID, $log_facility; + openlog($0, $openlog_option, $log_facility); } pipe($reader_pipe_one, $writer_pipe_one); diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index 8d9a23c0b..8c392c0d4 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -11,8 +11,8 @@ sub writeLogFile($$) { 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 LOG_ERR, $_[1] if ($_[0] == LOG_ESXD_ERROR); - syslog LOG_INFO, $_[1] if ($_[0] == LOG_ESXD_INFO); + syslog($syslog_err_priority, $_[1]) if ($_[0] == LOG_ESXD_ERROR); + syslog($syslog_info_priority, $_[1]) if ($_[0] == LOG_ESXD_INFO); } } diff --git a/connectors/vmware/lib/esxd-syslog.pm b/connectors/vmware/lib/esxd-syslog.pm new file mode 100644 index 000000000..29960b217 --- /dev/null +++ b/connectors/vmware/lib/esxd-syslog.pm @@ -0,0 +1,6 @@ + +$openlog_option = LOG_PID; +$syslog_err_priority = LOG_ERR; +$syslog_info_priority = LOG_INFO; + +1; From 3114bde2da67db2fdbb4e26b97e1d3408019ad5a Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 21 Sep 2012 13:49:16 +0000 Subject: [PATCH 012/447] =?UTF-8?q?Evolution=20#3974=20[vm]=20VMtools=20in?= =?UTF-8?q?stall=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@19 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 18 +++++++++- connectors/vmware/centreon_esxd | 2 ++ connectors/vmware/lib/command-toolsvm.pm | 46 ++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 connectors/vmware/lib/command-toolsvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index e35f4dd0f..13ee3773d 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -116,6 +116,9 @@ sub print_usage () { print " -w (--warning) Warning Threshold in percent (default 80)\n"; print " -c (--critical) Critical Threshold in percent (default 90)\n"; print "\n"; + print "'toolsvm':\n"; + print " --vm VM to check (required)\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -355,6 +358,19 @@ sub cpuvm_get_str { return "cpuvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub toolsvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub toolsvm_get_str { + return "toolsvm|" . $OPTION{'vm'}; +} + sub listhost_check_arg { return 0; } @@ -409,7 +425,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|toolsvm|listhost|listdatastore|listnichost|getmap)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index c186944e0..36d46c042 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -48,6 +48,7 @@ require $libpath . '/command-memhost.pm'; require $libpath . '/command-nethost.pm'; require $libpath . '/command-statushost.pm'; require $libpath . '/command-swaphost.pm'; +require $libpath . '/command-toolsvm.pm'; our $session_id; our %sockets = (); @@ -97,6 +98,7 @@ our %checks_descr = ( "memhost" => {'arg' => \&memhost_check_args, 'compute' => \&memhost_compute_args, 'exec' => \&memhost_do}, "swaphost" => {'arg' => \&swaphost_check_args, 'compute' => \&swaphost_compute_args, 'exec' => \&swaphost_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}, "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}, diff --git a/connectors/vmware/lib/command-toolsvm.pm b/connectors/vmware/lib/command-toolsvm.pm new file mode 100644 index 000000000..f3808dd11 --- /dev/null +++ b/connectors/vmware/lib/command-toolsvm.pm @@ -0,0 +1,46 @@ + +sub toolsvm_check_args { + my ($vm) = @_; + if (!defined($vm) || $vm eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm hostname\n"); + return 1; + } + return 0; +} + +sub toolsvm_compute_args { + my $lvm = $_[0]; + return ($lvm); +} + +sub toolsvm_do { + my ($lvm) = @_; + + my %filters = ('name' => $lvm); + my @properties = ('summary.guest.toolsStatus'); + my $result = get_entities_host('VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + my $tools_status = lc($$result[0]->{'summary.guest.toolsStatus'}->val); + if ($tools_status eq 'toolsnotinstalled') { + $output = "VMTools not installed on VM '$lvm'."; + $status |= $MYERRORS_MASK{'CRITICAL'}; + } elsif ($tools_status eq 'toolsnotrunning') { + $output = "VMTools not running on VM '$lvm'."; + $status |= $MYERRORS_MASK{'CRITICAL'}; + } elsif ($tools_status eq 'toolsold') { + $output = "VMTools not up-to-date on VM '$lvm'."; + $status |= $MYERRORS_MASK{'WARNING'}; + } else { + $output = "VMTools are OK on VM '$lvm'."; + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; From 2b76541fd8c48b7ba6011904025d6838f505eb62 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 21 Sep 2012 15:03:07 +0000 Subject: [PATCH 013/447] =?UTF-8?q?Evolution=20#3973=20[vm]=20V=C3=A9rifie?= =?UTF-8?q?r=20les=20snapshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@20 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 38 ++++++++++- connectors/vmware/centreon_esxd | 9 +++ connectors/vmware/lib/command-snapshotvm.pm | 75 +++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 connectors/vmware/lib/command-snapshotvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 13ee3773d..7b79d6699 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -39,6 +39,10 @@ GetOptions( "datastore=s" => \$OPTION{'datastore'}, "nic=s" => \$OPTION{'nic'}, + "older=i" => \$OPTION{'older'}, + "warn" => \$OPTION{'warn'}, + "crit" => \$OPTION{'crit'}, + "w|warning=i" => \$OPTION{'warning'}, "c|critical=i" => \$OPTION{'critical'}, ); @@ -119,6 +123,12 @@ sub print_usage () { print "'toolsvm':\n"; print " --vm VM to check (required)\n"; print "\n"; + print "'snapshotvm':\n"; + print " --vm VM to check (required)\n"; + print " --older If older than ms\n"; + print " --crit Critical if: there is a snasphot, or a snapshot is older than (--older)\n"; + print " --warn Warn if: there is a snasphot, or a snapshot is older than (--older)\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -371,6 +381,32 @@ sub toolsvm_get_str { return "toolsvm|" . $OPTION{'vm'}; } +sub snapshotvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'older'})) { + $OPTION{'older'} = ''; + } + if (!defined($OPTION{'warn'})) { + $OPTION{'warn'} = 0; + } else { + $OPTION{'warn'} = 1; + } + if (!defined($OPTION{'crit'})) { + $OPTION{'crit'} = 0; + } else { + $OPTION{'crit'} = 1; + } + return 0; +} + +sub snapshotvm_get_str { + return "snapshotvm|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'};; +} + sub listhost_check_arg { return 0; } @@ -425,7 +461,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|toolsvm|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|toolsvm|snapshotvm|listhost|listdatastore|listnichost|getmap)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 36d46c042..779f2a7f9 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -22,6 +22,13 @@ use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; +our $module_date_parse_loaded = 0; +eval 'require DateTime::Format::ISO8601'; +if (!$@) { + $module_date_parse_loaded = 1; + require DateTime::Format::ISO8601; +} + use vars qw($libpath $port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); use vars qw($LOG $log_mode $log_crit $log_facility); use vars qw($openlog_option $syslog_err_priority $syslog_info_priority); @@ -46,6 +53,7 @@ require $libpath . '/command-listnichost.pm'; require $libpath . '/command-maintenancehost.pm'; require $libpath . '/command-memhost.pm'; require $libpath . '/command-nethost.pm'; +require $libpath . '/command-snapshotvm.pm'; require $libpath . '/command-statushost.pm'; require $libpath . '/command-swaphost.pm'; require $libpath . '/command-toolsvm.pm'; @@ -99,6 +107,7 @@ our %checks_descr = ( "swaphost" => {'arg' => \&swaphost_check_args, 'compute' => \&swaphost_compute_args, 'exec' => \&swaphost_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}, "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}, diff --git a/connectors/vmware/lib/command-snapshotvm.pm b/connectors/vmware/lib/command-snapshotvm.pm new file mode 100644 index 000000000..ee84c064a --- /dev/null +++ b/connectors/vmware/lib/command-snapshotvm.pm @@ -0,0 +1,75 @@ + +sub snapshotvm_check_args { + my ($vm, $older) = @_; + if (!defined($vm) || $vm eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm hostname\n"); + return 1; + } + if (defined($older) && $older ne '' && $older !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: older arg must be a positive number\n"); + return 1; + } + return 0; +} + +sub snapshotvm_compute_args { + my $lvm = $_[0]; + my $older = ((defined($_[1]) and $_[1] ne '') ? $_[1] : -1); + my $warn = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); + my $crit = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); + return ($lvm, $older, $warn, $crit); +} + +sub snapshotvm_do { + my ($lvm, $older, $warn, $crit) = @_; + + if ($module_date_parse_loaded == 0) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 CPAN Module.\n"); + return ; + } + + my %filters = ('name' => $lvm); + my @properties = ('snapshot.rootSnapshotList'); + my $result = get_entities_host('VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Snapshot(s) OK'; + + if (!defined($$result[0]->{'snapshot.rootSnapshotList'})) { + $output = 'No current snapshot.'; + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); + return ; + } + + # 2012-09-21T14:16:17.540469Z + foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { + my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); + if ($older != -1 && time() - $create_time->epoch > $older) { + if ($warn == 1) { + $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($crit == 1) { + $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + } elsif ($older == -1) { + if ($warn == 1) { + $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($crit == 1) { + $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + } + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; From 9e63b4ca9c9fe0b2232cc9dcfc462637dc17ff71 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 21 Sep 2012 15:51:53 +0000 Subject: [PATCH 014/447] Evolution #3968 [vm] Disk check git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@21 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 20 ++- connectors/vmware/centreon_esxd | 2 + connectors/vmware/lib/command-datastoresvm.pm | 128 ++++++++++++++++++ 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 connectors/vmware/lib/command-datastoresvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 7b79d6699..ec5a2339b 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -129,6 +129,9 @@ sub print_usage () { print " --crit Critical if: there is a snasphot, or a snapshot is older than (--older)\n"; print " --warn Warn if: there is a snasphot, or a snapshot is older than (--older)\n"; print "\n"; + print "'datastoresvm':\n"; + print " --vm VM to check (required)\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -404,7 +407,20 @@ sub snapshotvm_check_arg { } sub snapshotvm_get_str { - return "snapshotvm|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'};; + return "snapshotvm|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; +} + +sub datastoresvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub datastoresvm_get_str { + return "datastoresvm|" . $OPTION{'vm'}; } sub listhost_check_arg { @@ -461,7 +477,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|toolsvm|snapshotvm|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|toolsvm|snapshotvm|datastoresvm|listhost|listdatastore|listnichost|getmap)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 779f2a7f9..9bbc29b79 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -44,6 +44,7 @@ require $libpath . '/command-cpuhost.pm'; require $libpath . '/command-cpuvm.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'; @@ -108,6 +109,7 @@ our %checks_descr = ( "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}, "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}, diff --git a/connectors/vmware/lib/command-datastoresvm.pm b/connectors/vmware/lib/command-datastoresvm.pm new file mode 100644 index 000000000..2692112d0 --- /dev/null +++ b/connectors/vmware/lib/command-datastoresvm.pm @@ -0,0 +1,128 @@ +sub datastoresvm_check_args { + my ($lvm) = @_; + if (!defined($lvm) || $lvm eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); + return 1; + } + return 0; +} + +sub datastoresvm_compute_args { + my $lvm = $_[0]; + return ($lvm); +} + +sub datastoresvm_do { + my ($lhost, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lhost); + my @properties = ('datastore'); + my $result = get_entities_host('VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @ds_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->datastore) { + @ds_array = (@ds_array, @{$entity_view->datastore}); + } + } + @properties = ('info'); + my $result2 = get_views(\@ds_array, \@properties); + if (!defined($result)) { + return ; + } + + #my %uuid_list = (); + my %disk_name = (); + my %datastore_lun = (); + foreach (@$result2) { + writeLogFile(1, Data::Dumper::Dumper($_)); + if ($_->info->vmfs->isa('HostVmfsVolume')) { + #$uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + foreach my $extent (@{$_->info->vmfs->extent}) { + $disk_name{$extent->diskName} = $_->info->vmfs->name; + if (!defined($datastore_lun{$_->info->vmfs->name})) { + %{$datastore_lun{$_->info->vmfs->name}} = (); + } + $datastore_lun{$_->info->vmfs->name}{$extent->diskName} = 0; + } + } + if ($_->info->vmfs->isa('HostNasVolume')) { + #$uuid_list{basename($_->mountInfo->path)} = $_->volume->name; + $disk_name{basename($_->info->mountInfo->path)} = $_->info->vmfs->name; + if (!defined($datastore_lun{$_->info->vmfs->name})) { + %{$datastore_lun{$_->info->vmfs->name}} = (); + } + $datastore_lun{$_->info->vmfs->name}{basename($_->info->mountInfo->path)} = 0; + } + } + + writeLogFile(1, Data::Dumper::Dumper(%datastore_lun)); + + # Vsphere >= 4.1 + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, + {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}, + {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + $perfcounter_speriod); + + writeLogFile(1, Data::Dumper::Dumper($values) . "\n"); + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $perfdata = ''; + foreach (keys %uuid_list) { + if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and + defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { + my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); + my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); + if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + + $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; + } + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Latency counter: $output_warning"; + } + if ($status == 0) { + $output = "All Datastore latency counters are ok"; + } + print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); +} + +1; From a77870789895d584b1f39a584710884258054612 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 25 Sep 2012 07:31:58 +0000 Subject: [PATCH 015/447] Last commit for 1.2 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@22 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 61 ++++++++++- connectors/vmware/centreon_esxd | 4 + connectors/vmware/lib/command-countvmhost.pm | 74 +++++++++++++ connectors/vmware/lib/command-datastoresvm.pm | 101 +++++++++--------- connectors/vmware/lib/command-memvm.pm | 77 +++++++++++++ 5 files changed, 267 insertions(+), 50 deletions(-) create mode 100644 connectors/vmware/lib/command-countvmhost.pm create mode 100644 connectors/vmware/lib/command-memvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index ec5a2339b..deb7e6b5d 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -115,6 +115,11 @@ sub print_usage () { print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; print "\n"; + print "'countvmhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold (default none)\n"; + print " -c (--critical) Critical Threshold (default none)\n"; + print "\n"; print "'cpuvm':\n"; print " --vm VM to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; @@ -131,6 +136,13 @@ sub print_usage () { print "\n"; print "'datastoresvm':\n"; print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in IOPS (default none)\n"; + print " -c (--critical) Critical Threshold in IOPS (default none)\n"; + print "\n"; + print "'memvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; print "\n"; print "'listhost':\n"; print " None\n"; @@ -352,6 +364,25 @@ sub nethost_get_str { return "nethost|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub countvmhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + return 0; +} + +sub countvmhost_get_str { + return "countvmhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + sub cpuvm_check_arg { if (!defined($OPTION{'vm'})) { print "Option --vm is required\n"; @@ -416,13 +447,39 @@ sub datastoresvm_check_arg { print_usage(); exit $ERRORS{'UNKNOWN'}; } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } return 0; } sub datastoresvm_get_str { - return "datastoresvm|" . $OPTION{'vm'}; + return "datastoresvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub memvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; +} + +sub memvm_get_str { + return "memvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + + sub listhost_check_arg { return 0; } @@ -477,7 +534,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|cpuvm|toolsvm|snapshotvm|datastoresvm|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|listhost|listdatastore|listnichost|getmap)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 9bbc29b79..2678c5fe4 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -42,6 +42,7 @@ 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'; @@ -53,6 +54,7 @@ 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'; @@ -106,10 +108,12 @@ our %checks_descr = ( "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}, "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}, "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}, diff --git a/connectors/vmware/lib/command-countvmhost.pm b/connectors/vmware/lib/command-countvmhost.pm new file mode 100644 index 000000000..9bf7e097e --- /dev/null +++ b/connectors/vmware/lib/command-countvmhost.pm @@ -0,0 +1,74 @@ +sub countvmhost_check_args { + my ($lhost, $warn, $crit) = @_; + if (!defined($lhost) || $lhost eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub countvmhost_compute_args { + my $lhost = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : ''); + my $crit = (defined($_[2]) ? $_[2] : ''); + return ($lhost, $warn, $crit); +} + +sub countvmhost_do { + my ($lhost, $warn, $crit) = @_; + + my %filters = ('name' => $lhost); + my @properties = ('vm'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @vm_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->vm) { + @vm_array = (@vm_array, @{$entity_view->vm}); + } + } + @properties = ('runtime.powerState'); + $result = get_views(\@vm_array, \@properties); + if (!defined($result)) { + return ; + } + + my $output = ''; + my $status = 0; # OK + my $num_poweron = 0; + + foreach (@$result) { + my $power_value = lc($_->{'runtime.powerState'}->val); + if ($power_value eq 'poweredon') { + $num_poweron++; + } + } + if (defined($crit) && $crit ne "" && ($num_poweron >= $crit)) { + $output = "CRITICAL: $num_poweron VM running."; + $status |= $MYERRORS_MASK{'CRITICAL'}; + } elsif (defined($warn) && $warn ne "" && ($num_poweron >= $warn)) { + $output = "WARNING: $num_poweron VM running."; + $status |= $MYERRORS_MASK{'WARNING'}; + } else { + $output = "OK: $num_poweron VM running."; + } + + print_response($ERRORS{$MYERRORS{$status}} . "|$output|count=$num_poweron\n"); +} + +1; diff --git a/connectors/vmware/lib/command-datastoresvm.pm b/connectors/vmware/lib/command-datastoresvm.pm index 2692112d0..5da5cf997 100644 --- a/connectors/vmware/lib/command-datastoresvm.pm +++ b/connectors/vmware/lib/command-datastoresvm.pm @@ -1,15 +1,29 @@ sub datastoresvm_check_args { - my ($lvm) = @_; + my ($lvm, $warn, $crit) = @_; if (!defined($lvm) || $lvm eq "") { writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); return 1; } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } return 0; } sub datastoresvm_compute_args { my $lvm = $_[0]; - return ($lvm); + my $warn = (defined($_[1]) ? $_[1] : ''); + my $crit = (defined($_[2]) ? $_[2] : ''); + return ($lvm, $warn, $crit); } sub datastoresvm_do { @@ -35,7 +49,7 @@ sub datastoresvm_do { } @properties = ('info'); my $result2 = get_views(\@ds_array, \@properties); - if (!defined($result)) { + if (!defined($result2)) { return ; } @@ -43,38 +57,31 @@ sub datastoresvm_do { my %disk_name = (); my %datastore_lun = (); foreach (@$result2) { - writeLogFile(1, Data::Dumper::Dumper($_)); - if ($_->info->vmfs->isa('HostVmfsVolume')) { + if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; # Not need. We are on Datastore level (not LUN level) foreach my $extent (@{$_->info->vmfs->extent}) { $disk_name{$extent->diskName} = $_->info->vmfs->name; if (!defined($datastore_lun{$_->info->vmfs->name})) { - %{$datastore_lun{$_->info->vmfs->name}} = (); + %{$datastore_lun{$_->info->vmfs->name}} = ('disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0); } - $datastore_lun{$_->info->vmfs->name}{$extent->diskName} = 0; } } - if ($_->info->vmfs->isa('HostNasVolume')) { - #$uuid_list{basename($_->mountInfo->path)} = $_->volume->name; - $disk_name{basename($_->info->mountInfo->path)} = $_->info->vmfs->name; - if (!defined($datastore_lun{$_->info->vmfs->name})) { - %{$datastore_lun{$_->info->vmfs->name}} = (); - } - $datastore_lun{$_->info->vmfs->name}{basename($_->info->mountInfo->path)} = 0; - } + #if ($_->info->isa('NasDatastoreInfo')) { + # Zero disk Info + #} } - writeLogFile(1, Data::Dumper::Dumper(%datastore_lun)); - # Vsphere >= 4.1 my $values = generic_performance_values_historic($$result[0], - [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, - {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}, + [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $perfcounter_speriod); - writeLogFile(1, Data::Dumper::Dumper($values) . "\n"); + foreach (keys %$values) { + my ($id, $disk_name) = split(/:/); + $datastore_lun{$disk_name{$disk_name}}{$perfcounter_cache_reverse{$id}} += $values->{$_}[0]; + } my $status = 0; # OK my $output = ''; @@ -84,43 +91,41 @@ sub datastoresvm_do { my $output_critical = ''; my $output_critical_append = ''; my $perfdata = ''; - foreach (keys %uuid_list) { - if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and - defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { - my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); - my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); - if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - - $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; + foreach (keys %datastore_lun) { + my $read_counter = simplify_number(convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $perfcounter_speriod)); + my $write_counter = simplify_number(convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $perfcounter_speriod)); + + if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $_ . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $_ . "' is $read_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; } + if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { + output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $_ . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { + output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $_ . "' is $write_counter ms"); + $status |= $MYERRORS_MASK{'WARNING'}; + } + + $perfdata .= " 'riops_" . $_ . "'=" . $read_counter . "iops 'wiops_" . $_ . "'=" . $write_counter . 'iops'; } if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; + $output .= $output_append . "CRITICAL - Datastore IOPS counter: $output_critical"; $output_append = ". "; } if ($output_warning ne "") { - $output .= $output_append . "WARNING - Latency counter: $output_warning"; + $output .= $output_append . "WARNING - Datastore IOPS counter: $output_warning"; } if ($status == 0) { - $output = "All Datastore latency counters are ok"; + $output = "All Datastore IOPS counters are ok"; } print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); } diff --git a/connectors/vmware/lib/command-memvm.pm b/connectors/vmware/lib/command-memvm.pm new file mode 100644 index 000000000..6d6884b2c --- /dev/null +++ b/connectors/vmware/lib/command-memvm.pm @@ -0,0 +1,77 @@ +sub memvm_check_args { + my ($vm, $warn, $crit) = @_; + if (!defined($vm) || $vm eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub memvm_compute_args { + my $lvm = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 80); + my $crit = (defined($_[2]) ? $_[2] : 90); + return ($lvm, $warn, $crit); +} + +sub memvm_do { + my ($lvm, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lvm); + my @properties = ('summary.config.memorySizeMB'); + my $result = get_entities_host('VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'mem.active.average', 'instances' => ['']}, + {'label' => 'mem.overhead.average', 'instances' => ['']}, + {'label' => 'mem.vmmemctl.average', 'instances' => ['']}, + {'label' => 'mem.consumed.average', 'instances' => ['']}, + {'label' => 'mem.shared.average', 'instances' => ['']}], + $perfcounter_speriod); + + writeLogFile(1, Data::Dumper::Dumper($values)); + + my $mem_consumed = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); + my $mem_active = simplify_number(convert_number($values->{$perfcounter_cache{'mem.active.average'}->{'key'} . ":"}[0])); + my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); + my $mem_ballooning = simplify_number(convert_number($values->{$perfcounter_cache{'mem.vmmemctl.average'}->{'key'} . ":"}[0])); + my $mem_shared = simplify_number(convert_number($values->{$perfcounter_cache{'mem.shared.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if ($mem_consumed * 100 / ($memory_size / 1024) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($mem_consumed * 100 / ($memory_size / 1024) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Memory usage : " . simplify_number($mem_consumed / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_consumed * 100 / ($memory_size / 1024)) . " %"; + $output .= "|usage=" . ($mem_consumed * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o" . " ballooning=" . ($mem_ballooning * 1024) . "o" . " shared=" . ($mem_shared * 1024) . "o" . " active=" . ($mem_active * 1024) . "o" ; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; From 06601c1878b21baa5c4fd0503c075876cf589a1c Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 26 Sep 2012 12:35:14 +0000 Subject: [PATCH 016/447] check second if there is really an error. git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@25 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/esxd-common.pm | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index 8c392c0d4..0b9de8d61 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -160,7 +160,7 @@ sub get_entities_host { eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; - if ($@ =~ /decryption failed or bad record mac/) { + if ($@) { writeLogFile(LOG_ESXD_ERROR, "$@"); eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); @@ -172,12 +172,6 @@ sub get_entities_host { print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); return undef; } - } elsif ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); - my $lerror = $@; - $lerror =~ s/\n/ /g; - print_response("-1|Error: " . $lerror . "\n"); - return undef; } if (!@$entity_views) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; From d2478a3025afa6e7eb62097315deb93f6cce2dc6 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 26 Sep 2012 12:44:34 +0000 Subject: [PATCH 017/447] Version in file git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@28 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 2 +- connectors/vmware/centreon_esxd | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index deb7e6b5d..571017552 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.0"; +my $VERSION = "1.2"; my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); my $socket; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 2678c5fe4..c8a2de18e 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -1,6 +1,5 @@ #!/usr/bin/perl -w - BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; $ENV{ESX_SYSLOGD_LOAD} = 0; @@ -17,7 +16,6 @@ use VMware::VIRuntime; use VMware::VILib; use IO::Socket; use File::Basename; -use Net::hostent; # for OOish version of gethostbyaddr use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; @@ -61,6 +59,7 @@ require $libpath . '/command-statushost.pm'; require $libpath . '/command-swaphost.pm'; require $libpath . '/command-toolsvm.pm'; +our $VERSION = "1.2"; our $session_id; our %sockets = (); our %child_proc; From ff1e7cc5812db3873aacb79bbcfd46b6d9b8736c Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 26 Sep 2012 14:23:13 +0000 Subject: [PATCH 018/447] avoid to have perl module when you only want to check snapshotvm git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@31 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/command-snapshotvm.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/lib/command-snapshotvm.pm b/connectors/vmware/lib/command-snapshotvm.pm index ee84c064a..8ac2f9df2 100644 --- a/connectors/vmware/lib/command-snapshotvm.pm +++ b/connectors/vmware/lib/command-snapshotvm.pm @@ -23,7 +23,7 @@ sub snapshotvm_compute_args { sub snapshotvm_do { my ($lvm, $older, $warn, $crit) = @_; - if ($module_date_parse_loaded == 0) { + if ($older != -1 && $module_date_parse_loaded == 0) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 CPAN Module.\n"); return ; @@ -45,10 +45,10 @@ sub snapshotvm_do { return ; } - # 2012-09-21T14:16:17.540469Z foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { - my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); if ($older != -1 && time() - $create_time->epoch > $older) { + # 2012-09-21T14:16:17.540469Z + my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); if ($warn == 1) { $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; $status |= $MYERRORS_MASK{'WARNING'}; @@ -59,11 +59,11 @@ sub snapshotvm_do { } } elsif ($older == -1) { if ($warn == 1) { - $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; + $output = 'There is at least one snapshot.'; $status |= $MYERRORS_MASK{'WARNING'}; } if ($crit == 1) { - $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; + $output = 'There is at least one snapshot.'; $status |= $MYERRORS_MASK{'CRITICAL'}; } } From ccca4470eac49d99ca94019b738684acc26fdc37 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 28 Sep 2012 13:44:03 +0000 Subject: [PATCH 019/447] Bug fix git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@34 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/command-statushost.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/lib/command-statushost.pm b/connectors/vmware/lib/command-statushost.pm index eac151302..b1895175c 100644 --- a/connectors/vmware/lib/command-statushost.pm +++ b/connectors/vmware/lib/command-statushost.pm @@ -38,12 +38,12 @@ sub statushost_do { ); foreach my $entity_view (@$result) { - my $status = $entity_view->{'summary.overallStatus'}->val; + my $status_esx = $entity_view->{'summary.overallStatus'}->val; - if (defined($status) && $overallStatus{$status}) { - $output = "The Server '$lhost' " . $overallStatus{$status}; - if ($MYERRORS_MASK{$overallStatusReturn{$status}} != 0) { - $status |= $MYERRORS_MASK{$overallStatusReturn{$status}}; + if (defined($status) && $overallStatus{$status_esx}) { + $output = "The Server '$lhost' " . $overallStatus{$status_esx}; + if ($MYERRORS_MASK{$overallStatusReturn{$status_esx}} != 0) { + $status |= $MYERRORS_MASK{$overallStatusReturn{$status_esx}}; } } else { $output = "Can't interpret data..."; From 619751031e6a33be0c3204e8e198f5a9c3b1b51d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 09:31:06 +0000 Subject: [PATCH 020/447] Evolution #3958 Gestion de plusieurs VirtualCenter git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@37 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 62 +++++----- connectors/vmware/centreon_esxd | 130 +++++++++++++------- connectors/vmware/centreon_esxd-conf.pm | 10 +- connectors/vmware/lib/command-snapshotvm.pm | 10 +- connectors/vmware/lib/esxd-common.pm | 9 +- 5 files changed, 141 insertions(+), 80 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 571017552..29728ae8d 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.2"; +my $VERSION = "1.0"; my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); my $socket; @@ -17,6 +17,7 @@ sub print_revision($$); my %OPTION = ( "help" => undef, "version" => undef, "esxd-host" => undef, "esxd-port" => 5700, + "vsphere" => '', "usage" => undef, "esx-host" => undef, "datastore" => undef, @@ -32,6 +33,8 @@ GetOptions( "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, + "vsphere=s" => \$OPTION{'vsphere'}, + "u|usage=s" => \$OPTION{'usage'}, "e|esx-host=s" => \$OPTION{'esx-host'}, "vm=s" => \$OPTION{'vm'}, @@ -68,6 +71,7 @@ sub print_usage () { print " -h (--help) usage help\n"; print " -H centreon-esxd Host (required)\n"; print " -P centreon-esxd Port (default 5700)\n"; + print " --vsphere vsphere name (default: none)\n"; print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; print "'healthhost':\n"; @@ -197,7 +201,7 @@ sub maintenancehost_check_arg { } sub maintenancehost_get_str { - return "maintenancehost|" . $OPTION{'esx-host'}; + return "maintenancehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub statushost_check_arg { @@ -210,7 +214,7 @@ sub statushost_check_arg { } sub statushost_get_str { - return "statushost|" . $OPTION{'esx-host'}; + return "statushost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub healthhost_check_arg { @@ -223,7 +227,7 @@ sub healthhost_check_arg { } sub healthhost_get_str { - return "healthhost|" . $OPTION{'esx-host'}; + return "healthhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub datastoreusage_check_arg { @@ -242,7 +246,7 @@ sub datastoreusage_check_arg { } sub datastoreusage_get_str { - return "datastoreusage|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastoreusage|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub datastoreio_check_arg { @@ -261,7 +265,7 @@ sub datastoreio_check_arg { } sub datastoreio_get_str { - return "datastoreio|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastoreio|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub cpuhost_check_arg { @@ -280,7 +284,7 @@ sub cpuhost_check_arg { } sub cpuhost_get_str { - return "cpuhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "cpuhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub datastoreshost_check_arg { @@ -299,7 +303,7 @@ sub datastoreshost_check_arg { } sub datastoreshost_get_str { - return "datastoreshost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastoreshost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub memhost_check_arg { @@ -318,7 +322,7 @@ sub memhost_check_arg { } sub memhost_get_str { - return "memhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "memhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub swaphost_check_arg { @@ -337,7 +341,7 @@ sub swaphost_check_arg { } sub swaphost_get_str { - return "swaphost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "swaphost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub nethost_check_arg { @@ -361,7 +365,7 @@ sub nethost_check_arg { } sub nethost_get_str { - return "nethost|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "nethost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub countvmhost_check_arg { @@ -380,7 +384,7 @@ sub countvmhost_check_arg { } sub countvmhost_get_str { - return "countvmhost|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "countvmhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub cpuvm_check_arg { @@ -399,7 +403,7 @@ sub cpuvm_check_arg { } sub cpuvm_get_str { - return "cpuvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "cpuvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub toolsvm_check_arg { @@ -412,7 +416,7 @@ sub toolsvm_check_arg { } sub toolsvm_get_str { - return "toolsvm|" . $OPTION{'vm'}; + return "toolsvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'}; } sub snapshotvm_check_arg { @@ -438,7 +442,7 @@ sub snapshotvm_check_arg { } sub snapshotvm_get_str { - return "snapshotvm|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; + return "snapshotvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; } sub datastoresvm_check_arg { @@ -457,7 +461,7 @@ sub datastoresvm_check_arg { } sub datastoresvm_get_str { - return "datastoresvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastoresvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub memvm_check_arg { @@ -476,7 +480,7 @@ sub memvm_check_arg { } sub memvm_get_str { - return "memvm|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "memvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } @@ -485,7 +489,7 @@ sub listhost_check_arg { } sub listhost_get_str { - return "listhost"; + return "listhost|" . $OPTION{'vsphere'}; } sub listdatastore_check_arg { @@ -493,7 +497,7 @@ sub listdatastore_check_arg { } sub listdatastore_get_str { - return "listdatastore"; + return "listdatastore|" . $OPTION{'vsphere'}; } sub listnichost_check_arg { @@ -506,7 +510,7 @@ sub listnichost_check_arg { } sub listnichost_get_str { - return "listnichost|" . $OPTION{'esx-host'}; + return "listnichost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub getmap_check_arg { @@ -517,7 +521,7 @@ sub getmap_check_arg { } sub getmap_get_str { - return "getmap|" . $OPTION{'esx-host'}; + return "getmap|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } ################# @@ -561,11 +565,11 @@ if ($status_return == -1) { } exit $status_return; -#print $remote "healthhost|srvi-esx-dev-1.merethis.net\n"; -#print $remote "datastores|LUN-VMFS-QGARNIER|80|90\n"; -#print $remote "maintenancehost|srvi-esx-dev-1.merethis.net\n"; -#print $remote "statushost|srvi-esx-dev-1.merethis.net\n"; -#print $remote "cpuhost|srvi-esx-dev-1.merethis.net|60\n"; -#print $remote "nethost|srvi-esx-dev-1.merethis.net|vmnic1|60\n"; -#print $remote "memhost|srvi-esx-dev-1.merethis.net|80\n"; -#print $remote "swaphost|srvi-esx-dev-1.merethis.net|80\n"; +#print $remote "healthhost||srvi-esx-dev-1.merethis.net\n"; +#print $remote "datastores||LUN-VMFS-QGARNIER|80|90\n"; +#print $remote "maintenancehost||srvi-esx-dev-1.merethis.net\n"; +#print $remote "statushost||srvi-esx-dev-1.merethis.net\n"; +#print $remote "cpuhost||srvi-esx-dev-1.merethis.net|60\n"; +#print $remote "nethost||srvi-esx-dev-1.merethis.net|vmnic1|60\n"; +#print $remote "memhost||srvi-esx-dev-1.merethis.net|80\n"; +#print $remote "swaphost||srvi-esx-dev-1.merethis.net|80\n"; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index c8a2de18e..2078477f2 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -1,5 +1,6 @@ #!/usr/bin/perl -w + BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; $ENV{ESX_SYSLOGD_LOAD} = 0; @@ -16,6 +17,7 @@ use VMware::VIRuntime; use VMware::VILib; use IO::Socket; use File::Basename; +use Net::hostent; # for OOish version of gethostbyaddr use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; @@ -27,7 +29,7 @@ if (!$@) { require DateTime::Format::ISO8601; } -use vars qw($libpath $port $service_url $username $password $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); +use vars qw($libpath $port %vsphere_server $TIMEOUT_VSPHERE $TIMEOUT $TIMEOUT_KILL $REFRESH_KEEPER_SESSION); use vars qw($LOG $log_mode $log_crit $log_facility); use vars qw($openlog_option $syslog_err_priority $syslog_info_priority); @@ -59,7 +61,6 @@ require $libpath . '/command-statushost.pm'; require $libpath . '/command-swaphost.pm'; require $libpath . '/command-toolsvm.pm'; -our $VERSION = "1.2"; our $session_id; our %sockets = (); our %child_proc; @@ -77,13 +78,11 @@ our $stop = 0; our $counter_request_id = 0; our $child_vpshere_pid; our $read_select; -our $reader_pipe_one; -our $writer_pipe_one; -our $reader_pipe_two; -our $writer_pipe_two; our $session1; our $counter = 0; our $global_id; +our $whoaim; # to know which vsphere to connect +our %filenos; our $openlog_option; our $syslog_err_priority; @@ -135,13 +134,14 @@ sub 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 $writer_pipe_one "$_|-1|Timeout Process.\n"; + print $handle_writer_pipe "$_|-1|Timeout Process.\n"; kill('INT', $child_proc{$_}->{'pid'}); $read_select->remove($handle); close $handle; @@ -163,8 +163,12 @@ sub verify_child { 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($reader_pipe_two); + $read_select->add($handle_reader_pipe); while (1) { my $progress = verify_child(); @@ -184,7 +188,7 @@ sub vsphere_handler { $session1->logout(); }; } - print $writer_pipe_one "STOPPED\n"; + print $handle_writer_pipe "STOPPED|$whoaim\n"; exit (0); } @@ -199,7 +203,7 @@ sub vsphere_handler { }; } if ($vsphere_connected == 0) { - if (!connect_vsphere()) { + if (!connect_vsphere($vsphere_server{$whoaim}->{'url'}, $vsphere_server{$whoaim}->{'username'}, $vsphere_server{$whoaim}->{'password'})) { writeLogFile(LOG_ESXD_INFO, "Vsphere connection ok\n"); writeLogFile(LOG_ESXD_INFO, "Create perf counters cache in progress\n"); if (!cache_perf_counters()) { @@ -223,7 +227,7 @@ sub vsphere_handler { }; if ($@) { writeLogFile(LOG_ESXD_ERROR, "$@"); - writeLogFile(LOG_ESXD_ERROR, "Ask a new connection"); + writeLogFile(LOG_ESXD_ERROR, "Ask a new connection\n"); # Ask a new connection $last_time_check = time(); } else { @@ -244,7 +248,7 @@ sub vsphere_handler { @rh_set = $read_select->can_read(0); } foreach my $rh (@rh_set) { - if ($rh == $reader_pipe_two && !$stop) { + if (fileno($rh) == $fileno_reader && !$stop) { $data_element = <$rh>; chomp $data_element; if ($data_element =~ /^STOP$/) { @@ -281,7 +285,7 @@ sub vsphere_handler { close $writer; } } else { - print $writer_pipe_one "$id|-1|Vsphere connection error.\n"; + print $handle_writer_pipe "$id|-1|Vsphere connection error.\n"; } } else { # Read pipe @@ -294,7 +298,7 @@ sub vsphere_handler { $last_time_check = $child_proc{$lid}->{'ctime'}; } chomp $output; - print $writer_pipe_one "$lid|$output\n"; + print $handle_writer_pipe "$lid|$output\n"; delete $return_child{$child_proc{$lid}->{'pid'}}; delete $child_proc{$lid}; } @@ -314,10 +318,6 @@ if ($log_mode == 2) { openlog($0, $openlog_option, $log_facility); } -pipe($reader_pipe_one, $writer_pipe_one); -pipe($reader_pipe_two, $writer_pipe_two); -$writer_pipe_one->autoflush(1); -$writer_pipe_two->autoflush(1); my $server = IO::Socket::INET->new( Proto => "tcp", LocalPort => $port, @@ -328,32 +328,58 @@ if (!$server) { exit(1); } -$child_vpshere_pid = fork(); -if (!$child_vpshere_pid) { - close $reader_pipe_one; - close $writer_pipe_two; - vsphere_handler(); - exit(0); + +## +# 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'}; } -close $writer_pipe_one; -close $reader_pipe_two; $read_select = new IO::Select(); $read_select->add($server); -$read_select->add($reader_pipe_one); +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(30); if ($stop == 1) { writeLogFile(LOG_ESXD_INFO, "Send STOP command to thread.\n"); - print $writer_pipe_two "STOP\n"; + foreach (keys %vsphere_server) { + my $writer_handle = $vsphere_server{$_}->{'writer_two'}; + print $writer_handle "STOP\n"; + } $stop = 2; } foreach my $rh (@rh_set) { - if (!$stop && $rh == $server) { + my $current_fileno = fileno($rh); + if (!$stop && $current_fileno == $socket_fileno) { my $client; - # Connect to accept $client = $rh->accept(); $client->autoflush(1); @@ -361,16 +387,26 @@ while (1) { $sockets{fileno($client)} = {"obj" => \$client, "ctime" => time(), "counter" => $counter}; $read_select->add($client); next; - } elsif ($rh == $reader_pipe_one) { + } elsif (defined($filenos{$current_fileno})) { # Return to read my $data_element = <$rh>; chomp $data_element; - if ($data_element =~ /^STOPPED$/) { - writeLogFile(LOG_ESXD_INFO, "Thread has stopped\n"); - exit(0); + 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; } - # Verify responde queue - #print "Response queue = $data_element\n"; my @results = split(/\|/, $data_element); my ($id, $counter) = split(/\./, $results[0]); if (!defined($sockets{$id}) || $counter != $sockets{$id}->{'counter'}) { @@ -389,25 +425,35 @@ while (1) { my $line = <$rh>; if (defined($line) && $line ne "") { chomp $line; - my ($name, @args) = split /\|/, $line; + my ($name, $vsphere_name, @args) = split /\|/, $line; if (!defined($checks_descr{$name})) { $rh->send("3|Unknown method name '$name'\n"); - delete $sockets{fileno($rh)}; + delete $sockets{$current_fileno}; $read_select->remove($rh); close $rh; next; } if ($checks_descr{$name}->{'arg'}(@args)) { $rh->send("3|Params error '$name'\n"); - delete $sockets{fileno($rh)}; + delete $sockets{$current_fileno}; $read_select->remove($rh); close $rh; next; } - print $writer_pipe_two fileno($rh) . "." . $sockets{fileno($rh)}->{'counter'} . "|$line\n"; + $vsphere_name = 'default' if (!defined($vsphere_name) || $vsphere_name eq ''); + if (!defined($vsphere_server{$vsphere_name})) { + $rh->send("3|Vsphere name unknown\n"); + delete $sockets{$current_fileno}; + $read_select->remove($rh); + close $rh; + next; + } + + my $tmp_handle = ${$vsphere_server{$vsphere_name}->{'writer_two'}}; + print $tmp_handle $current_fileno . "." . $sockets{$current_fileno}->{'counter'} . "|$name|@args\n"; } else { - delete $sockets{fileno($rh)}; + delete $sockets{$current_fileno}; $rh->send("3|Need arguments\n"); $read_select->remove($rh); close $rh; diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index 64942f13d..7afe5459b 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -1,9 +1,13 @@ our $libpath = '/usr/share/centreon/lib/centreon-esxd'; our $port = 5700; -our $service_url = "https://XXXX.XXXX.XXX/sdk"; -our $username = "xxxxx"; -our $password = 'xxxxx'; +our %vsphere_server = ('default' => {'url' => 'https://XXXXXX/sdk', + 'username' => 'XXXXX', + 'password' => 'XXXXX'}, + 'testvc' => {'url' => 'https://XXXXXX/sdk', + 'username' => 'XXXXX', + 'password' => 'XXXXXX'} + ); our $TIMEOUT_VSPHERE = 60; our $TIMEOUT = 60; our $TIMEOUT_KILL = 30; diff --git a/connectors/vmware/lib/command-snapshotvm.pm b/connectors/vmware/lib/command-snapshotvm.pm index 8ac2f9df2..ee84c064a 100644 --- a/connectors/vmware/lib/command-snapshotvm.pm +++ b/connectors/vmware/lib/command-snapshotvm.pm @@ -23,7 +23,7 @@ sub snapshotvm_compute_args { sub snapshotvm_do { my ($lvm, $older, $warn, $crit) = @_; - if ($older != -1 && $module_date_parse_loaded == 0) { + if ($module_date_parse_loaded == 0) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 CPAN Module.\n"); return ; @@ -45,10 +45,10 @@ sub snapshotvm_do { return ; } + # 2012-09-21T14:16:17.540469Z foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { + my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); if ($older != -1 && time() - $create_time->epoch > $older) { - # 2012-09-21T14:16:17.540469Z - my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); if ($warn == 1) { $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; $status |= $MYERRORS_MASK{'WARNING'}; @@ -59,11 +59,11 @@ sub snapshotvm_do { } } elsif ($older == -1) { if ($warn == 1) { - $output = 'There is at least one snapshot.'; + $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; $status |= $MYERRORS_MASK{'WARNING'}; } if ($crit == 1) { - $output = 'There is at least one snapshot.'; + $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; $status |= $MYERRORS_MASK{'CRITICAL'}; } } diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index 0b9de8d61..5e1e80c3d 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -17,6 +17,7 @@ sub writeLogFile($$) { } sub connect_vsphere { + my ($service_url, $username, $password) = @_; writeLogFile(LOG_ESXD_INFO, "Vsphere connection in progress\n"); eval { $SIG{ALRM} = sub { die('TIMEOUT'); }; @@ -160,7 +161,7 @@ sub get_entities_host { eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; - if ($@) { + if ($@ =~ /decryption failed or bad record mac/) { writeLogFile(LOG_ESXD_ERROR, "$@"); eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); @@ -172,6 +173,12 @@ sub get_entities_host { print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); return undef; } + } elsif ($@) { + writeLogFile(LOG_ESXD_ERROR, "$@"); + my $lerror = $@; + $lerror =~ s/\n/ /g; + print_response("-1|Error: " . $lerror . "\n"); + return undef; } if (!@$entity_views) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; From 642c14fc911ed0832af50001ec9ccaa155942151 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 09:36:20 +0000 Subject: [PATCH 021/447] Evolution #3958 Gestion de plusieurs VirtualCenter git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@38 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 16 ++++++++-------- connectors/vmware/lib/esxd-common.pm | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 2078477f2..a0818441d 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -176,7 +176,7 @@ sub vsphere_handler { # Manage ending ##### if ($stop && $timeout_process > $TIMEOUT_KILL) { - writeLogFile(LOG_ESXD_ERROR, "Kill child not gently.\n"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Kill child not gently.\n"); foreach (keys %child_proc) { kill('INT', $child_proc{$_}->{'pid'}); } @@ -196,7 +196,7 @@ sub vsphere_handler { # Manage vpshere connection ### if (defined($last_time_vsphere) && defined($last_time_check) && $last_time_vsphere < $last_time_check) { - writeLogFile(LOG_ESXD_ERROR, "Deconnect\n"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Deconnect\n"); $vsphere_connected = 0; eval { $session1->logout(); @@ -204,13 +204,13 @@ sub vsphere_handler { } if ($vsphere_connected == 0) { if (!connect_vsphere($vsphere_server{$whoaim}->{'url'}, $vsphere_server{$whoaim}->{'username'}, $vsphere_server{$whoaim}->{'password'})) { - writeLogFile(LOG_ESXD_INFO, "Vsphere connection ok\n"); - writeLogFile(LOG_ESXD_INFO, "Create perf counters cache in progress\n"); + 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, "Create perf counters cache done\n"); + writeLogFile(LOG_ESXD_INFO, "'$whoaim' Create perf counters cache done\n"); } } } @@ -227,11 +227,11 @@ sub vsphere_handler { }; if ($@) { writeLogFile(LOG_ESXD_ERROR, "$@"); - writeLogFile(LOG_ESXD_ERROR, "Ask a new connection\n"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' Ask a new connection\n"); # Ask a new connection $last_time_check = time(); } else { - writeLogFile(LOG_ESXD_INFO, "Get current time = " . Data::Dumper::Dumper($stime)); + writeLogFile(LOG_ESXD_INFO, "'$whoaim' Get current time = " . Data::Dumper::Dumper($stime)); } } @@ -259,7 +259,7 @@ sub vsphere_handler { my ($id) = split(/\|/, $data_element); if ($vsphere_connected) { - writeLogFile(LOG_ESXD_INFO, "vpshere handler asking: $data_element\n"); + writeLogFile(LOG_ESXD_INFO, "vpshere '$whoaim' handler asking: $data_element\n"); $child_proc{$id} = {'ctime' => time()}; my $reader; diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index 5e1e80c3d..102a2ac56 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -18,7 +18,7 @@ sub writeLogFile($$) { sub connect_vsphere { my ($service_url, $username, $password) = @_; - writeLogFile(LOG_ESXD_INFO, "Vsphere connection in progress\n"); + writeLogFile(LOG_ESXD_INFO, "'$whoaim' Vsphere connection in progress\n"); eval { $SIG{ALRM} = sub { die('TIMEOUT'); }; alarm($TIMEOUT_VSPHERE); @@ -29,9 +29,9 @@ sub connect_vsphere { alarm(0); }; if($@) { - writeLogFile(LOG_ESXD_ERROR, "No response from VirtualCentre server\n") if($@ =~ /TIMEOUT/); - writeLogFile(LOG_ESXD_ERROR, "You need to upgrade HTTP::Message!\n") if($@ =~ /HTTP::Message/); - writeLogFile(LOG_ESXD_ERROR, "Login to VirtualCentre server failed: $@"); + 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 { @@ -73,7 +73,7 @@ sub get_views { $results = $session1->get_views(mo_ref_array => $_[0], properties => $_[1]); }; if ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); my $lerror = $@; $lerror =~ s/\n/ /g; print_response("-1|Error: " . $lerror . "\n"); @@ -124,7 +124,7 @@ sub generic_performance_values_historic { } }; if ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); return undef; } return \%results; @@ -148,7 +148,7 @@ sub cache_perf_counters { } }; if ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); return 1; } return 0; @@ -162,19 +162,19 @@ sub get_entities_host { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; if ($@ =~ /decryption failed or bad record mac/) { - writeLogFile(LOG_ESXD_ERROR, "$@"); + 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, "$@"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); my $lerror = $@; $lerror =~ s/\n/ /g; print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); return undef; } } elsif ($@) { - writeLogFile(LOG_ESXD_ERROR, "$@"); + writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); my $lerror = $@; $lerror =~ s/\n/ /g; print_response("-1|Error: " . $lerror . "\n"); From c4cdaceee496d50e78e23da735f8b65176ee0f42 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 09:46:34 +0000 Subject: [PATCH 022/447] Evolution #3958 Gestion de plusieurs VirtualCenter git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@39 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 2 +- connectors/vmware/centreon_esxd | 5 ++-- connectors/vmware/lib/command-snapshotvm.pm | 28 +++++++++++---------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 29728ae8d..932f1f11a 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.0"; +my $VERSION = "1.3"; my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); my $socket; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index a0818441d..46a2d3149 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -17,7 +17,6 @@ use VMware::VIRuntime; use VMware::VILib; use IO::Socket; use File::Basename; -use Net::hostent; # for OOish version of gethostbyaddr use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; @@ -61,6 +60,8 @@ require $libpath . '/command-statushost.pm'; require $libpath . '/command-swaphost.pm'; require $libpath . '/command-toolsvm.pm'; + +our $VERSION = "1.3"; our $session_id; our %sockets = (); our %child_proc; @@ -451,7 +452,7 @@ while (1) { } my $tmp_handle = ${$vsphere_server{$vsphere_name}->{'writer_two'}}; - print $tmp_handle $current_fileno . "." . $sockets{$current_fileno}->{'counter'} . "|$name|@args\n"; + print $tmp_handle $current_fileno . "." . $sockets{$current_fileno}->{'counter'} . "|$name|" . join('|', @args) . "\n"; } else { delete $sockets{$current_fileno}; $rh->send("3|Need arguments\n"); diff --git a/connectors/vmware/lib/command-snapshotvm.pm b/connectors/vmware/lib/command-snapshotvm.pm index ee84c064a..2c6f2b3f4 100644 --- a/connectors/vmware/lib/command-snapshotvm.pm +++ b/connectors/vmware/lib/command-snapshotvm.pm @@ -23,7 +23,7 @@ sub snapshotvm_compute_args { sub snapshotvm_do { my ($lvm, $older, $warn, $crit) = @_; - if ($module_date_parse_loaded == 0) { + if ($older != -1 && $module_date_parse_loaded == 0) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 CPAN Module.\n"); return ; @@ -45,25 +45,27 @@ sub snapshotvm_do { return ; } - # 2012-09-21T14:16:17.540469Z foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { - my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); - if ($older != -1 && time() - $create_time->epoch > $older) { - if ($warn == 1) { - $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($crit == 1) { - $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; - $status |= $MYERRORS_MASK{'CRITICAL'}; + if ($older != -1) { + # 2012-09-21T14:16:17.540469Z + my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); + if (time() - $create_time->epoch > $older) { + if ($warn == 1) { + $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; + $status |= $MYERRORS_MASK{'WARNING'}; + } + if ($crit == 1) { + $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; + $status |= $MYERRORS_MASK{'CRITICAL'}; + } } } elsif ($older == -1) { if ($warn == 1) { - $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; + $output = 'There is at least one snapshot.'; $status |= $MYERRORS_MASK{'WARNING'}; } if ($crit == 1) { - $output = 'There is at least one snapshot (' . $snapshot->createTime . ').'; + $output = 'There is at least one snapshot.'; $status |= $MYERRORS_MASK{'CRITICAL'}; } } From 397f505699aaa40cc0f3a8e69e24407fa6b93a67 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 12:17:43 +0000 Subject: [PATCH 023/447] Evolution #3971 Statistiques git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@40 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 20 +++++++++++++++- connectors/vmware/centreon_esxd | 29 +++++++++--------------- connectors/vmware/lib/esxd-common.pm | 26 +++++++++++++++++++++ 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 932f1f11a..406548d3b 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -159,6 +159,10 @@ sub print_usage () { print "\n"; print "'getmap':\n"; print " -e (--esx-host) Esx Host to check\n"; + print "\n"; + print "'stats':\n"; + print " -w (--warning) Warning Threshold in total client connections (default none)\n"; + print " -c (--critical) Critical Threshold in total client connections (default none)\n"; } sub print_help () { @@ -524,6 +528,20 @@ sub getmap_get_str { return "getmap|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } +sub stats_check_arg { + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ""; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ""; + } + return 0; +} + +sub stats_get_str { + return "stats||" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + ################# ################# @@ -538,7 +556,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|listhost|listdatastore|listnichost|getmap)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 46a2d3149..a35a78432 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -368,10 +368,10 @@ foreach (keys %vsphere_server) { my $socket_fileno = fileno($server); writeLogFile(LOG_ESXD_INFO, "[Server accepting clients]\n"); while (1) { - my @rh_set = $read_select->can_read(30); + my @rh_set = $read_select->can_read(15); if ($stop == 1) { - writeLogFile(LOG_ESXD_INFO, "Send STOP command to thread.\n"); 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"; } @@ -427,37 +427,30 @@ while (1) { 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})) { - $rh->send("3|Unknown method name '$name'\n"); - delete $sockets{$current_fileno}; - $read_select->remove($rh); - close $rh; + response_client1($rh, $current_fileno, "3|Unknown method name '$name'\n"); next; } if ($checks_descr{$name}->{'arg'}(@args)) { - $rh->send("3|Params error '$name'\n"); - delete $sockets{$current_fileno}; - $read_select->remove($rh); - close $rh; + 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})) { - $rh->send("3|Vsphere name unknown\n"); - delete $sockets{$current_fileno}; - $read_select->remove($rh); - close $rh; + 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 { - delete $sockets{$current_fileno}; - $rh->send("3|Need arguments\n"); - $read_select->remove($rh); - close $rh; + response_client1($rh, $current_fileno, "3|Need arguments\n"); } } } diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index 102a2ac56..f07074c6e 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -16,6 +16,14 @@ sub writeLogFile($$) { } } +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"); @@ -198,4 +206,22 @@ sub get_entities_host { 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; From 4cbffb12354d880131144fcb5b4431bf7a992701 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 12:51:06 +0000 Subject: [PATCH 024/447] =?UTF-8?q?Evolution=20#4012=20[vm]=20V=C3=A9rific?= =?UTF-8?q?ation=20du=20swap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@41 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 26 ++++++++- connectors/vmware/centreon_esxd | 2 + connectors/vmware/lib/command-swaphost.pm | 3 +- connectors/vmware/lib/command-swapvm.pm | 67 +++++++++++++++++++++++ 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 connectors/vmware/lib/command-swapvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 406548d3b..91b24083a 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -148,6 +148,11 @@ sub print_usage () { print " -w (--warning) Warning Threshold in percent (default 80)\n"; print " -c (--critical) Critical Threshold in percent (default 90)\n"; print "\n"; + print "'swapvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -487,6 +492,25 @@ sub memvm_get_str { return "memvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub swapvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 0.8; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 1; + } + return 0; +} + +sub swapvm_get_str { + return "swapvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; +} + sub listhost_check_arg { return 0; @@ -556,7 +580,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index a35a78432..5c6bdd2aa 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -58,6 +58,7 @@ 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'; @@ -113,6 +114,7 @@ our %checks_descr = ( "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}, diff --git a/connectors/vmware/lib/command-swaphost.pm b/connectors/vmware/lib/command-swaphost.pm index 31bfc5bb0..089e193d6 100644 --- a/connectors/vmware/lib/command-swaphost.pm +++ b/connectors/vmware/lib/command-swaphost.pm @@ -35,8 +35,7 @@ sub swaphost_do { } my %filters = ('name' => $lhost); - #my @properties = ('summary'); - my @properties = (); + my @properties = ('name'); my $result = get_entities_host('HostSystem', \%filters, \@properties); if (!defined($result)) { return ; diff --git a/connectors/vmware/lib/command-swapvm.pm b/connectors/vmware/lib/command-swapvm.pm new file mode 100644 index 000000000..7a4d24a43 --- /dev/null +++ b/connectors/vmware/lib/command-swapvm.pm @@ -0,0 +1,67 @@ +sub swapvm_check_args { + my ($vm, $warn, $crit) = @_; + if (!defined($vm) || $vm eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); + return 1; + } + return 0; +} + +sub swapvm_compute_args { + my $lvm = $_[0]; + my $warn = (defined($_[1]) ? $_[1] : 0.8); + my $crit = (defined($_[2]) ? $_[2] : 1); + return ($lvm, $warn, $crit); +} + +sub swapvm_do { + my ($lvm, $warn, $crit) = @_; + if (!($perfcounter_speriod > 0)) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $lvm); + my @properties = ('name'); + my $result = get_entities_host('VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = generic_performance_values_historic($$result[0], + [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, + {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], + $perfcounter_speriod); + + my $swap_in = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapinRate.average'}->{'key'} . ":"}[0])); + my $swap_out = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if (($swap_in / 1024) >= $warn || ($swap_out / 1024) >= $warn) { + $status |= $MYERRORS_MASK{'WARNING'}; + } + if (($swap_in / 1024) >= $crit || ($swap_out / 1024) >= $crit) { + $status |= $MYERRORS_MASK{'CRITICAL'}; + } + + $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; + $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; From 5d11abb2e544d80ab56279585734b2c4b2bbd6aa Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 13:05:52 +0000 Subject: [PATCH 025/447] fix wrong commit git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@42 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/esxd-common.pm | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index f07074c6e..a64d6b6f4 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -169,7 +169,7 @@ sub get_entities_host { eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); }; - if ($@ =~ /decryption failed or bad record mac/) { + if ($@) { writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); eval { $entity_views = $session1->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); @@ -181,12 +181,6 @@ sub get_entities_host { print_response("-1|Error: " . Data::Dumper::Dumper($lerror) . "\n"); return undef; } - } elsif ($@) { - writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); - my $lerror = $@; - $lerror =~ s/\n/ /g; - print_response("-1|Error: " . $lerror . "\n"); - return undef; } if (!@$entity_views) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; From 8aa332fa74fcf21a6ce00524bb85b2d3bf3821e5 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 13:34:23 +0000 Subject: [PATCH 026/447] Evolution #3992 [host] Avoir uniquement l'average totale dans les perfdata git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@43 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 8 +++++++- connectors/vmware/lib/command-cpuhost.pm | 9 +++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 91b24083a..640045bb6 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -19,6 +19,7 @@ my %OPTION = ( "esxd-host" => undef, "esxd-port" => 5700, "vsphere" => '', "usage" => undef, + "light-perfdata" => undef, "esx-host" => undef, "datastore" => undef, "nic" => undef, @@ -39,6 +40,7 @@ GetOptions( "e|esx-host=s" => \$OPTION{'esx-host'}, "vm=s" => \$OPTION{'vm'}, + "light-perfdata" => \$OPTION{'light-perfdata'}, "datastore=s" => \$OPTION{'datastore'}, "nic=s" => \$OPTION{'nic'}, @@ -97,6 +99,7 @@ sub print_usage () { print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " --light-perfdata Display only total average cpu perfdata\n"; print "\n"; print "'nethost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -289,11 +292,14 @@ sub cpuhost_check_arg { if (!defined($OPTION{'critical'})) { $OPTION{'critical'} = 90; } + if (!defined($OPTION{'light-perfdata'})) { + $OPTION{'light-perfdata'} = 0; + } return 0; } sub cpuhost_get_str { - return "cpuhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "cpuhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'light-perfdata'}; } sub datastoreshost_check_arg { diff --git a/connectors/vmware/lib/command-cpuhost.pm b/connectors/vmware/lib/command-cpuhost.pm index 5aae3ec62..864aa737a 100644 --- a/connectors/vmware/lib/command-cpuhost.pm +++ b/connectors/vmware/lib/command-cpuhost.pm @@ -1,5 +1,5 @@ sub cpuhost_check_args { - my ($host, $warn, $crit) = @_; + my ($host, $warn, $crit, $light_perfdata) = @_; if (!defined($host) || $host eq "") { writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); return 1; @@ -23,11 +23,12 @@ sub cpuhost_compute_args { my $lhost = $_[0]; my $warn = (defined($_[1]) ? $_[1] : 80); my $crit = (defined($_[2]) ? $_[2] : 90); - return ($lhost, $warn, $crit); + my $light_perfdata = (defined($_[3]) ? $_[3] : 0); + return ($lhost, $warn, $crit, $light_perfdata); } sub cpuhost_do { - my ($lhost, $warn, $crit) = @_; + my ($lhost, $warn, $crit, $light_perfdata) = @_; if (!($perfcounter_speriod > 0)) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); @@ -66,7 +67,7 @@ sub cpuhost_do { $cib = -1 if (!defined($cib) || $cib eq ""); $cia <=> $cib} keys %$values) { my ($counter_id, $instance) = split /:/, $id; - if ($instance ne "") { + if ($instance ne "" and $light_perfdata != 1) { $output .= " cpu$instance=" . simplify_number(convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; } } From e77a7a75298304f241a55672720e9a916c58881d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 8 Oct 2012 13:53:28 +0000 Subject: [PATCH 027/447] Evolution #3991 [host] Filtrer les datastores git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@44 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 7 +++++- .../vmware/lib/command-datastoreshost.pm | 22 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 640045bb6..acefa1625 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -40,6 +40,7 @@ GetOptions( "e|esx-host=s" => \$OPTION{'esx-host'}, "vm=s" => \$OPTION{'vm'}, + "filter-datastores=s" => \$OPTION{'filter-datastores'}, "light-perfdata" => \$OPTION{'light-perfdata'}, "datastore=s" => \$OPTION{'datastore'}, "nic=s" => \$OPTION{'nic'}, @@ -121,6 +122,7 @@ sub print_usage () { print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; + print " --filter-datastores Datastores to verify (separated by coma)\n"; print "\n"; print "'countvmhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -314,11 +316,14 @@ sub datastoreshost_check_arg { if (!defined($OPTION{'critical'})) { $OPTION{'critical'} = ''; } + if (!defined($OPTION{'filter-datastores'})) { + $OPTION{'filter-datastores'} = ''; + } return 0; } sub datastoreshost_get_str { - return "datastoreshost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastoreshost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'filter-datastores'}; } sub memhost_check_arg { diff --git a/connectors/vmware/lib/command-datastoreshost.pm b/connectors/vmware/lib/command-datastoreshost.pm index b230422ae..b936e4fd0 100644 --- a/connectors/vmware/lib/command-datastoreshost.pm +++ b/connectors/vmware/lib/command-datastoreshost.pm @@ -23,11 +23,20 @@ sub datastoreshost_compute_args { my $lhost = $_[0]; my $warn = (defined($_[1]) ? $_[1] : ''); my $crit = (defined($_[2]) ? $_[2] : ''); - return ($lhost, $warn, $crit); + my $filter_ds = (defined($_[3]) ? $_[3] : ''); + return ($lhost, $warn, $crit, $filter_ds); } sub datastoreshost_do { - my ($lhost, $warn, $crit) = @_; + my ($lhost, $warn, $crit, $filter_ds) = @_; + + my %valid_ds = (); + my $filter_ok = 0; + if ($filter_ds ne '') { + foreach (split /,/, $filter_ds) { + $valid_ds{$_} = 1; + } + } if (!($perfcounter_speriod > 0)) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); @@ -71,6 +80,9 @@ sub datastoreshost_do { my $output_critical_append = ''; my $perfdata = ''; foreach (keys %uuid_list) { + if ($filter_ds ne '' and !defined($valid_ds{$uuid_list{$_}})) { + next; + } if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); @@ -94,10 +106,16 @@ sub datastoreshost_do { $status |= $MYERRORS_MASK{'WARNING'}; } + $filter_ok = 1; $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; } } + if ($filter_ds ne '' and $filter_ok == 0) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Datastore names in filter are unknown.\n"); + return ; + } if ($output_critical ne "") { $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; $output_append = ". "; From 8171400253a5de6a60db98319f0044b6e0067991 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 7 Dec 2012 15:07:56 +0000 Subject: [PATCH 028/447] bug fix: error when you have use wrong nic name git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@46 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/command-nethost.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/lib/command-nethost.pm b/connectors/vmware/lib/command-nethost.pm index bb230fd51..510eb8a98 100644 --- a/connectors/vmware/lib/command-nethost.pm +++ b/connectors/vmware/lib/command-nethost.pm @@ -55,7 +55,7 @@ sub nethost_do { if (!defined($pnic_def{$pnic})) { my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print $ERRORS{$MYERRORS{$status}} . "|Link '$pnic' not exist or down.\n"; + print_response($ERRORS{$MYERRORS{$status}} . "|Link '$pnic' not exist or down.\n"); return ; } From dffa8b3a7ba3be7f0bd586d401b60853bfd8e0cb Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 4 Feb 2013 16:48:08 +0000 Subject: [PATCH 029/447] Fix #4861 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@47 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 18 +++++++++++++++++- connectors/vmware/centreon_esxd | 3 +++ connectors/vmware/lib/command-snapshotvm.pm | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index acefa1625..952e06d0a 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -129,6 +129,9 @@ sub print_usage () { print " -w (--warning) Warning Threshold (default none)\n"; print " -c (--critical) Critical Threshold (default none)\n"; print "\n"; + print "'uptimehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; print "'cpuvm':\n"; print " --vm VM to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; @@ -407,6 +410,19 @@ sub countvmhost_get_str { return "countvmhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub uptimehost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; +} + +sub uptimehost_get_str { + return "uptimehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; +} + sub cpuvm_check_arg { if (!defined($OPTION{'vm'})) { print "Option --vm is required\n"; @@ -591,7 +607,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 5c6bdd2aa..7a2b5679a 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -2,6 +2,7 @@ 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;'; @@ -60,6 +61,7 @@ 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'; our $VERSION = "1.3"; @@ -109,6 +111,7 @@ our %checks_descr = ( "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}, diff --git a/connectors/vmware/lib/command-snapshotvm.pm b/connectors/vmware/lib/command-snapshotvm.pm index 2c6f2b3f4..0d16c4fc8 100644 --- a/connectors/vmware/lib/command-snapshotvm.pm +++ b/connectors/vmware/lib/command-snapshotvm.pm @@ -47,6 +47,12 @@ sub snapshotvm_do { foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { if ($older != -1) { + if ($module_date_parse_loaded == 0) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 Perl Module.\n"); + return ; + } + # 2012-09-21T14:16:17.540469Z my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); if (time() - $create_time->epoch > $older) { From d153fe1bfd50da8badadd5acf8310d013ff7fd7c Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 4 Feb 2013 16:49:21 +0000 Subject: [PATCH 030/447] Fix #4861 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@48 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 2 +- connectors/vmware/lib/command-uptimehost.pm | 43 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 connectors/vmware/lib/command-uptimehost.pm diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 7a2b5679a..7bf17050f 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -64,7 +64,7 @@ require $libpath . '/command-toolsvm.pm'; require $libpath . '/command-uptimehost.pm'; -our $VERSION = "1.3"; +our $VERSION = "1.3.1"; our $session_id; our %sockets = (); our %child_proc; diff --git a/connectors/vmware/lib/command-uptimehost.pm b/connectors/vmware/lib/command-uptimehost.pm new file mode 100644 index 000000000..71a7784d5 --- /dev/null +++ b/connectors/vmware/lib/command-uptimehost.pm @@ -0,0 +1,43 @@ +sub uptimehost_check_args { + my ($lhost) = @_; + if (!defined($lhost) || $lhost eq "") { + writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); + return 1; + } + return 0; +} + +sub uptimehost_compute_args { + my $lhost = $_[0]; + return ($lhost); +} + +sub uptimehost_do { + my ($lhost) = @_; + + my %filters = ('name' => $lhost); + my @properties = ('runtime.bootTime'); + my $result = get_entities_host('HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + if ($module_date_parse_loaded == 0) { + my $status |= $MYERRORS_MASK{'UNKNOWN'}; + print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 Perl Module.\n"); + return ; + } + + my $create_time = DateTime::Format::ISO8601->parse_datetime($$result[0]->{'runtime.bootTime'}); + my $diff_time = time() - $create_time->epoch; + my $days = int($diff_time / 60 / 60 / 24); + + my $output = ''; + my $status = 0; # OK + + $output = "Uptime (in day): $days|uptime=" . $days . "day(s)\n"; + + print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); +} + +1; From 3572b61ed40ca233c64fa4bb053b81733d8e674b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 5 Feb 2013 09:52:54 +0000 Subject: [PATCH 031/447] Fix #4862 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@49 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 30 ++++++++++++++++++++++++- connectors/vmware/centreon_esxd-conf.pm | 3 +++ connectors/vmware/lib/command-memvm.pm | 4 +--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 7bf17050f..fd2e721c8 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -30,6 +30,7 @@ if (!$@) { } 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); @@ -63,7 +64,6 @@ require $libpath . '/command-swapvm.pm'; require $libpath . '/command-toolsvm.pm'; require $libpath . '/command-uptimehost.pm'; - our $VERSION = "1.3.1"; our $session_id; our %sockets = (); @@ -96,6 +96,34 @@ if ($ENV{ESX_SYSLOGD_LOAD} == 1) { require $libpath . '/esxd-syslog.pm'; } +##### 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; + + if (VMware::VICredStore::init(filename => $credstore_file) == 0) { + writeLogFile("Credstore init failed: $@\n"); + exit(1); + } + + ### + # Get password + ### + foreach (keys %vsphere_server) { + my $lpassword = VMware::VICredStore::get_password(server => $_, username => $vsphere_server{$_}->{'username'}); + if (!defined($lpassword)) { + writeLogFile("Can't get password for couple host='" . $_ . "', username='" . $vsphere_server{$_}->{'username'} . "' : $@\n"); + exit(1); + } + $vsphere_server{$_}->{'password'} = $lpassword; + } +} + 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); diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index 7afe5459b..033771b84 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -8,6 +8,9 @@ our %vsphere_server = ('default' => {'url' => 'https://XXXXXX/sdk', 'username' => 'XXXXX', '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; diff --git a/connectors/vmware/lib/command-memvm.pm b/connectors/vmware/lib/command-memvm.pm index 6d6884b2c..3d184120c 100644 --- a/connectors/vmware/lib/command-memvm.pm +++ b/connectors/vmware/lib/command-memvm.pm @@ -41,7 +41,7 @@ sub memvm_do { return ; } - $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; + my $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; my $values = generic_performance_values_historic($$result[0], [{'label' => 'mem.active.average', 'instances' => ['']}, @@ -51,8 +51,6 @@ sub memvm_do { {'label' => 'mem.shared.average', 'instances' => ['']}], $perfcounter_speriod); - writeLogFile(1, Data::Dumper::Dumper($values)); - my $mem_consumed = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); my $mem_active = simplify_number(convert_number($values->{$perfcounter_cache{'mem.active.average'}->{'key'} . ":"}[0])); my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); From 232eff04dc4d813fe56f5db0f1146037d2890190 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 5 Feb 2013 09:57:23 +0000 Subject: [PATCH 032/447] Fix log error git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@50 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index fd2e721c8..5d3934a71 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -107,7 +107,7 @@ if (defined($credstore_use) && defined($credstore_file) && require VMware::VICredStore; if (VMware::VICredStore::init(filename => $credstore_file) == 0) { - writeLogFile("Credstore init failed: $@\n"); + writeLogFile(LOG_ESXD_ERROR, "Credstore init failed: $@\n"); exit(1); } @@ -117,7 +117,7 @@ if (defined($credstore_use) && defined($credstore_file) && foreach (keys %vsphere_server) { my $lpassword = VMware::VICredStore::get_password(server => $_, username => $vsphere_server{$_}->{'username'}); if (!defined($lpassword)) { - writeLogFile("Can't get password for couple host='" . $_ . "', username='" . $vsphere_server{$_}->{'username'} . "' : $@\n"); + writeLogFile(LOG_ESXD_ERROR, "Can't get password for couple host='" . $_ . "', username='" . $vsphere_server{$_}->{'username'} . "' : $@\n"); exit(1); } $vsphere_server{$_}->{'password'} = $lpassword; From 967d577d8b3277ee417f544347476682f6f82eab Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 6 Feb 2013 15:47:39 +0000 Subject: [PATCH 033/447] Fix #4863 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@51 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/command-cpuhost.pm | 2 +- connectors/vmware/lib/command-cpuvm.pm | 2 +- connectors/vmware/lib/esxd-common.pm | 34 +++++++++++++++++------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/connectors/vmware/lib/command-cpuhost.pm b/connectors/vmware/lib/command-cpuhost.pm index 864aa737a..1ff1d4896 100644 --- a/connectors/vmware/lib/command-cpuhost.pm +++ b/connectors/vmware/lib/command-cpuhost.pm @@ -59,7 +59,7 @@ sub cpuhost_do { $status |= $MYERRORS_MASK{'CRITICAL'}; } - $output = "Total Average CPU usage '$total_cpu_average%' on last " . ($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100"; + $output = "Total Average CPU usage '$total_cpu_average%' on last " . int($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100"; foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; diff --git a/connectors/vmware/lib/command-cpuvm.pm b/connectors/vmware/lib/command-cpuvm.pm index d8eda8544..67789cc52 100644 --- a/connectors/vmware/lib/command-cpuvm.pm +++ b/connectors/vmware/lib/command-cpuvm.pm @@ -61,7 +61,7 @@ sub cpuvm_do { $status |= $MYERRORS_MASK{'CRITICAL'}; } - $output = "Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . ($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; + $output = "Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . int($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index a64d6b6f4..787f83a84 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -116,16 +116,25 @@ sub generic_performance_values_historic { eval { my @perf_metric_ids = get_perf_metric_ids($perfs); - my (@t) = gmtime(time() - $interval); - my $start = sprintf("%04d-%02d-%02dT%02d:%02d:00Z", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1]); - my $perf_query_spec = PerfQuerySpec->new(entity => $view, - metricId => @perf_metric_ids, - format => 'normal', - intervalId => $interval, - startTime => $start - ); - #maxSample => 1); + my $perf_query_spec; + if ($interval == 20) { + $perf_query_spec = PerfQuerySpec->new(entity => $view, + metricId => @perf_metric_ids, + format => 'normal', + intervalId => 20, + maxSample => 1); + } else { + my (@t) = gmtime(time() - $interval); + my $start = sprintf("%04d-%02d-%02dT%02d:%02d:00Z", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1]); + $perf_query_spec = PerfQuerySpec->new(entity => $view, + metricId => @perf_metric_ids, + format => 'normal', + intervalId => $interval, + startTime => $start + ); + #maxSample => 1); + } my $perfdata = $perfmanager_view->QueryPerf(querySpec => $perf_query_spec); foreach (@{$$perfdata[0]->value}) { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; @@ -154,6 +163,11 @@ sub cache_perf_counters { $perfcounter_speriod = $_->samplingPeriod; } } + + # Put refresh = 20 (for ESX check) + if ($perfcounter_speriod == -1) { + $perfcounter_speriod = 20; + } }; if ($@) { writeLogFile(LOG_ESXD_ERROR, "'$whoaim' $@"); From 4086f2d396f3f3cb3126c67934b55983eb004942 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 13 Mar 2013 14:08:20 +0000 Subject: [PATCH 034/447] Fix git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@52 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index 5d3934a71..5492a2bde 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -2,7 +2,7 @@ BEGIN { - $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL"; + #$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;'; From 03856c27e659bff320d0ad8a2b9ef702595aacc9 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 18 Mar 2013 15:32:28 +0000 Subject: [PATCH 035/447] Bug fix: get interval value git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@53 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/esxd-common.pm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/lib/esxd-common.pm b/connectors/vmware/lib/esxd-common.pm index 787f83a84..9f8e19a8d 100644 --- a/connectors/vmware/lib/esxd-common.pm +++ b/connectors/vmware/lib/esxd-common.pm @@ -117,21 +117,29 @@ sub generic_performance_values_historic { 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 { - my (@t) = gmtime(time() - $interval); - my $start = sprintf("%04d-%02d-%02dT%02d:%02d:00Z", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1]); $perf_query_spec = PerfQuerySpec->new(entity => $view, metricId => @perf_metric_ids, format => 'normal', intervalId => $interval, - startTime => $start + startTime => $startTime, + endTime => $endTime ); #maxSample => 1); } From 4d658254a80cd69f1fb106f533d364fd4eca3bb1 Mon Sep 17 00:00:00 2001 From: Hozaifa Safla Date: Fri, 3 May 2013 15:07:48 +0000 Subject: [PATCH 036/447] First Documentation git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@54 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/doc/Makefile | 177 ++ .../doc/_build/doctrees/environment.pickle | Bin 0 -> 43441 bytes .../doctrees/exploitation/index.doctree | Bin 0 -> 341484 bytes .../vmware/doc/_build/doctrees/index.doctree | Bin 0 -> 5558 bytes .../doctrees/installation/index.doctree | Bin 0 -> 31121 bytes connectors/vmware/doc/_build/html/.buildinfo | 4 + .../vmware/doc/_build/html/_images/archi.png | Bin 0 -> 29775 bytes .../html/_sources/exploitation/index.txt | 1384 ++++++++++ .../vmware/doc/_build/html/_sources/index.txt | 24 + .../html/_sources/installation/index.txt | 191 ++ .../doc/_build/html/_static/ajax-loader.gif | Bin 0 -> 673 bytes .../vmware/doc/_build/html/_static/basic.css | 540 ++++ .../_build/html/_static/comment-bright.png | Bin 0 -> 3500 bytes .../doc/_build/html/_static/comment-close.png | Bin 0 -> 3578 bytes .../doc/_build/html/_static/comment.png | Bin 0 -> 3445 bytes .../doc/_build/html/_static/default.css | 256 ++ .../doc/_build/html/_static/doctools.js | 235 ++ .../doc/_build/html/_static/down-pressed.png | Bin 0 -> 368 bytes .../vmware/doc/_build/html/_static/down.png | Bin 0 -> 363 bytes .../vmware/doc/_build/html/_static/file.png | Bin 0 -> 392 bytes .../vmware/doc/_build/html/_static/jquery.js | 4 + .../vmware/doc/_build/html/_static/minus.png | Bin 0 -> 199 bytes .../vmware/doc/_build/html/_static/plus.png | Bin 0 -> 199 bytes .../doc/_build/html/_static/pygments.css | 62 + .../doc/_build/html/_static/searchtools.js | 622 +++++ .../vmware/doc/_build/html/_static/sidebar.js | 159 ++ .../doc/_build/html/_static/underscore.js | 31 + .../doc/_build/html/_static/up-pressed.png | Bin 0 -> 372 bytes .../vmware/doc/_build/html/_static/up.png | Bin 0 -> 363 bytes .../doc/_build/html/_static/websupport.js | 808 ++++++ .../doc/_build/html/exploitation/index.html | 2376 +++++++++++++++++ .../vmware/doc/_build/html/genindex.html | 92 + connectors/vmware/doc/_build/html/index.html | 133 + .../doc/_build/html/installation/index.html | 314 +++ connectors/vmware/doc/_build/html/objects.inv | Bin 0 -> 209 bytes connectors/vmware/doc/_build/html/search.html | 99 + .../vmware/doc/_build/html/searchindex.js | 1 + connectors/vmware/doc/conf.py | 248 ++ connectors/vmware/doc/exploitation/index.rst | 1384 ++++++++++ connectors/vmware/doc/images/archi.png | Bin 0 -> 29775 bytes connectors/vmware/doc/index.rst | 24 + connectors/vmware/doc/installation/index.rst | 191 ++ 42 files changed, 9359 insertions(+) create mode 100644 connectors/vmware/doc/Makefile create mode 100644 connectors/vmware/doc/_build/doctrees/environment.pickle create mode 100644 connectors/vmware/doc/_build/doctrees/exploitation/index.doctree create mode 100644 connectors/vmware/doc/_build/doctrees/index.doctree create mode 100644 connectors/vmware/doc/_build/doctrees/installation/index.doctree create mode 100644 connectors/vmware/doc/_build/html/.buildinfo create mode 100644 connectors/vmware/doc/_build/html/_images/archi.png create mode 100644 connectors/vmware/doc/_build/html/_sources/exploitation/index.txt create mode 100644 connectors/vmware/doc/_build/html/_sources/index.txt create mode 100644 connectors/vmware/doc/_build/html/_sources/installation/index.txt create mode 100644 connectors/vmware/doc/_build/html/_static/ajax-loader.gif create mode 100644 connectors/vmware/doc/_build/html/_static/basic.css create mode 100644 connectors/vmware/doc/_build/html/_static/comment-bright.png create mode 100644 connectors/vmware/doc/_build/html/_static/comment-close.png create mode 100644 connectors/vmware/doc/_build/html/_static/comment.png create mode 100644 connectors/vmware/doc/_build/html/_static/default.css create mode 100644 connectors/vmware/doc/_build/html/_static/doctools.js create mode 100644 connectors/vmware/doc/_build/html/_static/down-pressed.png create mode 100644 connectors/vmware/doc/_build/html/_static/down.png create mode 100644 connectors/vmware/doc/_build/html/_static/file.png create mode 100644 connectors/vmware/doc/_build/html/_static/jquery.js create mode 100644 connectors/vmware/doc/_build/html/_static/minus.png create mode 100644 connectors/vmware/doc/_build/html/_static/plus.png create mode 100644 connectors/vmware/doc/_build/html/_static/pygments.css create mode 100644 connectors/vmware/doc/_build/html/_static/searchtools.js create mode 100644 connectors/vmware/doc/_build/html/_static/sidebar.js create mode 100644 connectors/vmware/doc/_build/html/_static/underscore.js create mode 100644 connectors/vmware/doc/_build/html/_static/up-pressed.png create mode 100644 connectors/vmware/doc/_build/html/_static/up.png create mode 100644 connectors/vmware/doc/_build/html/_static/websupport.js create mode 100644 connectors/vmware/doc/_build/html/exploitation/index.html create mode 100644 connectors/vmware/doc/_build/html/genindex.html create mode 100644 connectors/vmware/doc/_build/html/index.html create mode 100644 connectors/vmware/doc/_build/html/installation/index.html create mode 100644 connectors/vmware/doc/_build/html/objects.inv create mode 100644 connectors/vmware/doc/_build/html/search.html create mode 100644 connectors/vmware/doc/_build/html/searchindex.js create mode 100644 connectors/vmware/doc/conf.py create mode 100644 connectors/vmware/doc/exploitation/index.rst create mode 100644 connectors/vmware/doc/images/archi.png create mode 100644 connectors/vmware/doc/index.rst create mode 100644 connectors/vmware/doc/installation/index.rst diff --git a/connectors/vmware/doc/Makefile b/connectors/vmware/doc/Makefile new file mode 100644 index 000000000..2370a79c0 --- /dev/null +++ b/connectors/vmware/doc/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CentreonESXD.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CentreonESXD.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/CentreonESXD" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CentreonESXD" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/connectors/vmware/doc/_build/doctrees/environment.pickle b/connectors/vmware/doc/_build/doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..22474718113e27fd68404a8b0bec9516aeb1207a GIT binary patch literal 43441 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 @FVtA4N)u`}jcjRX9f{I`+cytEA*OL-dG2r6 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

9{h2h~F;9n>s36#Fou4+B9-Yr#>{ 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 E2V%GDcK`qY literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/doctrees/index.doctree b/connectors/vmware/doc/_build/doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..62710a3d7f8535f68e49ca783f066598b558d2e8 GIT binary patch literal 5558 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 K9`IWq%={nn1=#-p literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/.buildinfo b/connectors/vmware/doc/_build/html/.buildinfo new file mode 100644 index 000000000..cd98838b0 --- /dev/null +++ b/connectors/vmware/doc/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 5c34505a03d196bacf5235352ea2ec0d +tags: a205e9ed8462ae86fdd2f73488852ba9 diff --git a/connectors/vmware/doc/_build/html/_images/archi.png b/connectors/vmware/doc/_build/html/_images/archi.png new file mode 100644 index 0000000000000000000000000000000000000000..82dca91fec4159d8be96155e65412aa0fd645059 GIT binary patch literal 29775 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 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc/_build/html/_sources/exploitation/index.txt new file mode 100644 index 000000000..c5657eb15 --- /dev/null +++ b/connectors/vmware/doc/_build/html/_sources/exploitation/index.txt @@ -0,0 +1,1384 @@ +============ +Exploitation +============ + +Présentation de Centreon-esxd +----------------------------- + +Principes Généraux +`````````````````` + +Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. + +Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : + +*« handle-client »*: + *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + +Voici le fonctionnement : + +- Un client se connecte. +- Le client demande un indicateur de supervision sur un VirtualCenter. +- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». +- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». +- Le processus « handle-client » fourni la réponse au client. + +*« handle-vsphere-xxxx »*: + *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* + +Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. + +Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. + +Voici un exemple d'architecture éclaté : + +.. image:: ../images/archi.png + +Mode de fonctionnement +`````````````````````` +Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). + +Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. + +Configuration du connecteur +``````````````````````````` +Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: + + 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', + 'password' => 'XXXXXX'} + 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"; + +La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. + +La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». + +Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. + +Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. + + +Optimisation de la configuration dans Centreon +---------------------------------------------- + +Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. + +Ce connecteur permet la définition de trois modèles d'hôtes : + +- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. +- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. +- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») + +Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. + ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | +| | | | ++====================+===================================================================+================================================================+ +| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ + +Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». + + +Création d'un modèle d'hôte VMWare générique +```````````````````````````````````````````` + +Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». + +Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. + +Définir les macros suivante : + ++---------------------+-------------------------------------------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+===================================================================+ +| ESXDHOST | Exemple: 10.30.10.30 | ++---------------------+-------------------------------------------------------------------+ +| ESXDPORT | 5700 (port par défaut) | ++---------------------+-------------------------------------------------------------------+ +| VCNAME | default | ++---------------------+-------------------------------------------------------------------+ + +Troubleshooting +``````````````` + +Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: + + ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... + +Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. + +Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. + + +Liste des contrôles +------------------- + +Contrôles ESX +````````````` +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++===========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuhost | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | +| | - le taux d'utilisation mémoire (en octets), | +| | - la taille totale de la mémoire (en octets), | +| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memhost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +RESEAU +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_nethost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux d'utilisation en entrée et sortie (en b/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | nethost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| NICNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +SWAP +'''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_swaphost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | swaphost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 0.8 | ++---------------------+--------------------------------+ +| CRITICAL | 1 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreshost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | +| | - la latence totale en lecture et écriture (en ms). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++============================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoreshost | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 30 | ++---------------------+--------------------------------+ +| CRITICAL | 50 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +COUNTVM +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_countvmhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | +| | - le nombre de machines virtuelles allumées. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | count=45 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | countvmhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 10 | ++---------------------+--------------------------------+ +| CRITICAL | 15 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +HEALTH +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_healthhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | Remonte un état selon l'état des sondes: | +| | - "Yellow" correspond à WARNING. | +| | - "Red" correspond à CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | healthhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MAINTENANCE +''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_maintenancehost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | maintenancehost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +STATUT +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_statushost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état global d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | +| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | +| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | statushost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôles d'une machine virtuelle +````````````````````````````````` + +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuvm | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | +| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | +| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | +| | - « overhead » : la mémoire sur-alloué (en octets) | +| | - « ballooning », « shared » et « active ». | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoresvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | +| | - « riops » : le nombre moyen d'I/O de lectures par seconde | +| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoresvm | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +VMTOOLS +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_toolsvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | +| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | toolsvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +SNAPSHOTS +''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_snapshotvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | L'état dépend des paramètres du plugin : | +| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | +| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | +| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | +| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++====================+==========================================================================================+================================================================+ +| -u | Indicateur à contrôler | snapshotvm | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| THRESHOLD | - -warn | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôle d'un datastore +``````````````````````` + +USAGE +''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreusage | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | +| | - « used » : l'espace occupé par le datastore (en octets) | +| | - « size » : la taille totale allouée pour le datastore (en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-usage | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORE I/O +''''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastorio | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | +| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | +| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-io | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + diff --git a/connectors/vmware/doc/_build/html/_sources/index.txt b/connectors/vmware/doc/_build/html/_sources/index.txt new file mode 100644 index 000000000..8f840209e --- /dev/null +++ b/connectors/vmware/doc/_build/html/_sources/index.txt @@ -0,0 +1,24 @@ +.. Centreon ESXD documentation master file, created by + sphinx-quickstart on Mon Apr 22 11:17:38 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Centreon ESXD's documentation! +========================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + installation/index + exploitation/index + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/connectors/vmware/doc/_build/html/_sources/installation/index.txt b/connectors/vmware/doc/_build/html/_sources/installation/index.txt new file mode 100644 index 000000000..3534d2c3c --- /dev/null +++ b/connectors/vmware/doc/_build/html/_sources/installation/index.txt @@ -0,0 +1,191 @@ +============ +Installation +============ + +Pré-Requis +========== + +Préconisations logicielles +`````````````````````````` + +Le connecteur "centreon-esxd" est testé et validé sur des environnements Linux. +L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Solaris, Windows, ...). + +==================== ===================== +Logiciels Version minimum +==================== ===================== +VMWare SDK Perl 5.0 +Perl 5.8 +centreon-esxd 1.3 +==================== ===================== + +Préconisations matérielles +`````````````````````````` + +Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n'effectue aucunes vérifications. Les ressources minimales sont de : + +* mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). + +* CPU : même pré-requis que pour le serveur de collecte. + +Installation de centreon-esxd - Environnement centos/rhel 5 +=========================================================== + +Installation du SDK Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay + + root # cpan install Class::MethodMaker + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + root # cpan install SOAP::Lite + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +Nous avons notre environnement prêt pour l'installation du SDK VMWare. + +Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_). + +Installer le SDK Perl VMWare:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Installation de modules complémentaires +``````````````````````````````````````` + +Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : + +Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: + + root # cpan install Unix::Syslog + +Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Ensuite redémarrer votre système. + +Installation de centreon-esxd +````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* + +Installation de centreon-esxd - Environnement centos/rhel 6 +=========================================================== + +Installation du sdk Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite + + root # cpan install Test::More + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +Nous avons notre environnement prêt pour l'installation du SDK VMWare. + +Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_) + +Installer le SDK Perl VMWare:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Installation de modules complémentaires +``````````````````````````````````````` + +Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : + +Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: + + root # cpan install Unix::Syslog + +Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Ensuite redémarrer votre système. + +Installation de centreon-esxd +````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* + + diff --git a/connectors/vmware/doc/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc/_build/html/_static/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..61faf8cab23993bd3e1560bff0668bd628642330 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@Cw{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_static/basic.css b/connectors/vmware/doc/_build/html/_static/basic.css new file mode 100644 index 000000000..a04c8e137 --- /dev/null +++ b/connectors/vmware/doc/_build/html/_static/basic.css @@ -0,0 +1,540 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/_static/comment-bright.png b/connectors/vmware/doc/_build/html/_static/comment-bright.png new file mode 100644 index 0000000000000000000000000000000000000000..551517b8c83b76f734ff791f847829a760ad1903 GIT binary patch literal 3500 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 A2LJ#7 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_static/comment.png b/connectors/vmware/doc/_build/html/_static/comment.png new file mode 100644 index 0000000000000000000000000000000000000000..92feb52b8824c6b0f59b658b1196c61de9162a95 GIT binary patch literal 3445 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 Xn!ZpXD%P(H00000NkvXXu0mjf= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('

') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/connectors/vmware/doc/_build/html/_static/down-pressed.png b/connectors/vmware/doc/_build/html/_static/down-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..6f7ad782782e4f8e39b0c6e15c7344700cdd2527 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}Z23@f-Ava~9&<9T!#}JFtXD=!G zGdl{fK6ro2OGiOl+hKvH6i=D3%%Y^j`yIkRn!8O>@bG)IQR0{Kf+mxNd=_WScA8u_ z3;8(7x2){m9`nt+U(Nab&1G)!{`SPVpDX$w8McLTzAJ39wprG3p4XLq$06M`%}2Yk zRPPsbES*dnYm1wkGL;iioAUB*Or2kz6(-M_r_#Me-`{mj$Z%( literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_static/down.png b/connectors/vmware/doc/_build/html/_static/down.png new file mode 100644 index 0000000000000000000000000000000000000000..3003a88770de3977d47a2ba69893436a2860f9e7 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}xaV3tUZ$qnrLa#kt978NlpS`ru z&)HFc^}^>{UOEce+71h5nn>6&w6A!ieNbu1wh)UGh{8~et^#oZ1# z>T7oM=FZ~xXWnTo{qnXm$ZLOlqGswI_m2{XwVK)IJmBjW{J3-B3x@C=M{ShWt#fYS9M?R;8K$~YwlIqwf>VA7q=YKcwf2DS4Zj5inDKXXB1zl=(YO3ST6~rDq)&z z*o>z)=hxrfG-cDBW0G$!?6{M<$@{_4{m1o%Ub!naEtn|@^frU1tDnm{r-UW|!^@B8 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_static/file.png b/connectors/vmware/doc/_build/html/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..d18082e397e7e54f20721af768c4c2983258f1b4 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP$HyOL$D9)yc9|lc|nKf<9@eUiWd>3GuTC!a5vdfWYEazjncPj5ZQX%+1 zt8B*4=d)!cdDz4wr^#OMYfqGz$1LDFF>|#>*O?AGil(WEs?wLLy{Gj2J_@opDm%`dlax3yA*@*N$G&*ukFv>P8+2CBWO(qz zD0k1@kN>hhb1_6`&wrCswzINE(evt-5C1B^STi2@PmdKI;Vst0PQB6!2kdN literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_static/jquery.js b/connectors/vmware/doc/_build/html/_static/jquery.js new file mode 100644 index 000000000..198b3ff07 --- /dev/null +++ b/connectors/vmware/doc/_build/html/_static/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/_static/minus.png b/connectors/vmware/doc/_build/html/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..da1c5620d10c047525a467a425abe9ff5269cfc2 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknK< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/_build/html/_static/pygments.css b/connectors/vmware/doc/_build/html/_static/pygments.css new file mode 100644 index 000000000..d79caa151 --- /dev/null +++ b/connectors/vmware/doc/_build/html/_static/pygments.css @@ -0,0 +1,62 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/_static/searchtools.js b/connectors/vmware/doc/_build/html/_static/searchtools.js new file mode 100644 index 000000000..56676b25b --- /dev/null +++ b/connectors/vmware/doc/_build/html/_static/searchtools.js @@ -0,0 +1,622 @@ +/* + * searchtools.js_t + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + + +/** + * Simple result scoring code. + */ +var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + // query found in terms + term: 5 +}; + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, + dataType: "script", cache: true, + complete: function(jqxhr, textstatus) { + if (textstatus != "success") { + document.getElementById("searchindexloader").src = url; + } + }}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + var i; + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + } + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

').appendTo(this.out); + this.output = $('
'); + } + // Prettify the comment rating. + comment.pretty_rating = comment.rating + ' point' + + (comment.rating == 1 ? '' : 's'); + // Make a class (for displaying not yet moderated comments differently) + comment.css_class = comment.displayed ? '' : ' moderate'; + // Create a div for this comment. + var context = $.extend({}, opts, comment); + var div = $(renderTemplate(commentTemplate, context)); + + // If the user has voted on this comment, highlight the correct arrow. + if (comment.vote) { + var direction = (comment.vote == 1) ? 'u' : 'd'; + div.find('#' + direction + 'v' + comment.id).hide(); + div.find('#' + direction + 'u' + comment.id).show(); + } + + if (opts.moderator || comment.text != '[deleted]') { + div.find('a.reply').show(); + if (comment.proposal_diff) + div.find('#sp' + comment.id).show(); + if (opts.moderator && !comment.displayed) + div.find('#cm' + comment.id).show(); + if (opts.moderator || (opts.username == comment.username)) + div.find('#dc' + comment.id).show(); + } + return div; + } + + /** + * A simple template renderer. Placeholders such as <%id%> are replaced + * by context['id'] with items being escaped. Placeholders such as <#id#> + * are not escaped. + */ + function renderTemplate(template, context) { + var esc = $(document.createElement('div')); + + function handle(ph, escape) { + var cur = context; + $.each(ph.split('.'), function() { + cur = cur[this]; + }); + return escape ? esc.text(cur || "").html() : cur; + } + + return template.replace(/<([%#])([\w\.]*)\1>/g, function() { + return handle(arguments[2], arguments[1] == '%' ? true : false); + }); + } + + /** Flash an error message briefly. */ + function showError(message) { + $(document.createElement('div')).attr({'class': 'popup-error'}) + .append($(document.createElement('div')) + .attr({'class': 'error-message'}).text(message)) + .appendTo('body') + .fadeIn("slow") + .delay(2000) + .fadeOut("slow"); + } + + /** Add a link the user uses to open the comments popup. */ + $.fn.comment = function() { + return this.each(function() { + var id = $(this).attr('id').substring(1); + var count = COMMENT_METADATA[id]; + var title = count + ' comment' + (count == 1 ? '' : 's'); + var image = count > 0 ? opts.commentBrightImage : opts.commentImage; + var addcls = count == 0 ? ' nocomment' : ''; + $(this) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-open' + addcls, + id: 'ao' + id + }) + .append($(document.createElement('img')).attr({ + src: image, + alt: 'comment', + title: title + })) + .click(function(event) { + event.preventDefault(); + show($(this).attr('id').substring(2)); + }) + ) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-close hidden', + id: 'ah' + id + }) + .append($(document.createElement('img')).attr({ + src: opts.closeCommentImage, + alt: 'close', + title: 'close' + })) + .click(function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }) + ); + }); + }; + + var opts = { + processVoteURL: '/_process_vote', + addCommentURL: '/_add_comment', + getCommentsURL: '/_get_comments', + acceptCommentURL: '/_accept_comment', + deleteCommentURL: '/_delete_comment', + commentImage: '/static/_static/comment.png', + closeCommentImage: '/static/_static/comment-close.png', + loadingImage: '/static/_static/ajax-loader.gif', + commentBrightImage: '/static/_static/comment-bright.png', + upArrow: '/static/_static/up.png', + downArrow: '/static/_static/down.png', + upArrowPressed: '/static/_static/up-pressed.png', + downArrowPressed: '/static/_static/down-pressed.png', + voting: false, + moderator: false + }; + + if (typeof COMMENT_OPTIONS != "undefined") { + opts = jQuery.extend(opts, COMMENT_OPTIONS); + } + + var popupTemplate = '\ +
\ +

\ + Sort by:\ + best rated\ + newest\ + oldest\ +

\ +
Comments
\ +
\ + loading comments...
\ +
    \ +
    \ +

    Add a comment\ + (markup):

    \ +
    \ + reStructured text markup: *emph*, **strong**, \ + ``code``, \ + code blocks: :: and an indented block after blank line
    \ +
    \ + \ +

    \ + \ + Propose a change ▹\ + \ + \ + Propose a change ▿\ + \ +

    \ + \ + \ + \ + \ + \ +
    \ +
    '; + + var commentTemplate = '\ +
    \ +
    \ +
    \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +
    \ +

    \ + <%username%>\ + <%pretty_rating%>\ + <%time.delta%>\ +

    \ +
    <#text#>
    \ +

    \ + \ + reply ▿\ + proposal ▹\ + proposal ▿\ + \ + \ +

    \ +
    \
    +<#proposal_diff#>\
    +        
    \ +
      \ +
      \ +
      \ +
      \ + '; + + var replyTemplate = '\ +
    • \ +
      \ +
      \ + \ + \ + \ + \ + \ + \ +
      \ +
    • '; + + $(document).ready(function() { + init(); + }); +})(jQuery); + +$(document).ready(function() { + // add comment anchors for all paragraphs that are commentable + $('.sphinx-has-comment').comment(); + + // highlight search words in search results + $("div.context").each(function() { + var params = $.getQueryParameters(); + var terms = (params.q) ? params.q[0].split(/\s+/) : []; + var result = $(this); + $.each(terms, function() { + result.highlightText(this.toLowerCase(), 'highlighted'); + }); + }); + + // directly open comment window if requested + var anchor = document.location.hash; + if (anchor.substring(0, 9) == '#comment-') { + $('#ao' + anchor.substring(9)).click(); + document.location.hash = '#s' + anchor.substring(9); + } +}); diff --git a/connectors/vmware/doc/_build/html/exploitation/index.html b/connectors/vmware/doc/_build/html/exploitation/index.html new file mode 100644 index 000000000..8982a0e59 --- /dev/null +++ b/connectors/vmware/doc/_build/html/exploitation/index.html @@ -0,0 +1,2376 @@ + + + + + + + + Exploitation — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Exploitation¶

      +
      +

      Présentation de Centreon-esxd¶

      +
      +

      Principes Généraux¶

      +

      Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d’un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter.

      +

      Par défaut, « centreon-esxd Â» lance au moins deux processus (nommé respectivement « handle-client Â», « handle-vsphere-xxxx Â») :

      +
      +
      « handle-client Â»:
      +
      Processus en attente des demandes des clients « centreon_esx_client.pl Â».
      +
      +

      Voici le fonctionnement :

      +
        +
      • Un client se connecte.
      • +
      • Le client demande un indicateur de supervision sur un VirtualCenter.
      • +
      • Le processus « handle-client Â» fourni cette demande au processus « handle-vsphere-xxxx Â».
      • +
      • Une réponse est fournie par « handle-vsphere-xxxx Â» à « handle-client Â».
      • +
      • Le processus « handle-client Â» fourni la réponse au client.
      • +
      +
      +
      « handle-vsphere-xxxx Â»:
      +
      Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).
      +
      +

      Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande.

      +

      Centreon-esxd nécessite impérativement l’utilisation d’un (ou plusieurs) VirtualCenter. Il n’est pas possible de récupérer les informations d’un serveur ESX directement.

      +

      Voici un exemple d’architecture éclaté :

      +../_images/archi.png +
      +
      +

      Mode de fonctionnement¶

      +

      Le programme « centreon-esxd Â» fonctionne uniquement en mode « daemon Â». (dans le sens où il ne peut fournir les indicateurs sans l’utilisation d’un client).

      +

      Lors de l’utilisation du plugin centreon_esx_client.pl, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans “/usr/share/centreon/lib/centreon-esxd” et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires.

      +
      +
      +

      Configuration du connecteur¶

      +

      Le daemon « centreon-esxd Â» possède un fichier de configuration « centreon_esxd.pm Â» de la forme suivante :

      +
      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',
      +                                   'password' => 'XXXXXX'}
      +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";
      +
      +

      La variable «%vsphere_server Â» permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d’avoir au moins l’entrée ‘default’.

      +

      La variable « $port Â» permet de configurer le port d’écoute du connecteur « centreon-esxd Â».

      +

      Il est aussi possible de modifier la variable « $log_mode Â» si vous souhaitez utiliser « syslog Â» au lieu d’un fichier à plat.

      +

      Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION Â», « $TIMEOUT_KILL Â», « $ TIMEOUT_VSPHERE Â» et « $TIMEOUT Â», car ils sont configurés pour une utilisation optimale.

      +
      +
      +
      +

      Optimisation de la configuration dans Centreon¶

      +

      Afin d’exploiter pleinement « centreon-esxd Â», il est recommandé d’effectuer une série d’action préalablement.

      +

      Ce connecteur permet la définition de trois modèles d’hôtes :

      +
        +
      • le modèle hôte « VMWare-VM Â» : modèle d’une machine virtuelle.
      • +
      • le modèle hôte « VMWare-ESX Â» : modèle d’un serveur ESX.
      • +
      • le modèle hôte « VMWare-VC Â» : modèle d’un virtualCenter (Ce modèle contient notamment des services pour les « datastores Â»)
      • +
      +

      Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration.

      +
      +++++ + + + + + + + + + + + + + + + + + + + + +
      Macro NameMacro ValueRessource ou la macro doit être défini (recommandé)
      HOSTESXDHOSTIp ou nom d’hôte du serveur exécutant le daemon « centreon-esxd Â»Modèle d’hôte VMWare-* de plus bas niveau
      HOSTESXDPORTPort du daemonModèle d’hôte VMWare-* de plus bas niveau
      HOSTVCNAMENom identifiant le VirtualCenterModèle d’hôte VMWare-* de plus bas niveau
      +

      Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm Â» qui se situe normalement dans “/etc/centreon/centreon_esxd.pm” . Ce système évite la visualisation d’un mot de passe dans l’interface « centreon Â».

      +
      +

      Création d’un modèle d’hôte VMWare générique¶

      +

      Aller dans le menu configuration/host/template/, et créer un modèle d’hôte « VMWare Â». Ce modèle d’hôte sera le modèle parent pour les modèles « VMWare-VM Â», « VMWare-ESX Â» et « VMWare-VC Â».

      +

      Configurer l’ensemble des champs comme indiqué dans la documentation Centreon.

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + + + + +
      Macro NameMacro Value
      ESXDHOSTExemple: 10.30.10.30
      ESXDPORT5700 (port par défaut)
      VCNAMEdefault
      +
      +
      +

      Troubleshooting¶

      +

      Il est possible de retrouver des erreurs de ce type dans les « log Â» de « centreon-esxd Â» :

      +
      ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac...
      +
      +
      +

      Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur.

      +

      Il est nécessaire de remonter un problème dans le cas d’un trop grand nombres de déconnexion du daemon au VirtualCenter.

      +
      + +
      +

      Liste des contrôles¶

      +
      +

      Contrôles ESX¶

      +
      +

      CPU¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_cpuhost
      DescriptionContrôle le taux d’utilisation CPU d’un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs.
      Fonctionnement
        +
      • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéescpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100
      Interval/Retry(min)5/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlercpuhost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
      --light-perfdata(optionnel) Permet d’afficher uniquement la perfdata du CPU total 
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING80
      CRITICAL90
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      MEMOIRE¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_memhost
      Description
      +
      Contrôle le taux d’utilisation mémoire d’un serveur ESX. 3 métriques sont renvoyés :
      +
        +
      • le taux d’utilisation mémoire (en octets),
      • +
      • la taille totale de la mémoire (en octets),
      • +
      • la mémoire suralloué par la totalité des VMs (‘overhead’ en octets)
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéesused=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o
      Interval/Retry(min)20/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlermemhost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING80
      CRITICAL90
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      RESEAU¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_nethost
      Description
      +
      Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés :
      +
        +
      • le taux d’utilisation en entrée et sortie (en b/s).
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la(les) métrique(s) « traffic_* Â» est(sont) au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéestraffic_in=598016b/s traffic_out=172032b/s
      Interval/Retry(min)5/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlernethost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      --nicNom de l’interface réseau physiquevmnic0
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + + + + +
      Macro NameMacro Value
      NICNAME 
      WARNING80
      CRITICAL90
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$"
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      SWAP¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_swaphost
      Description
      +
      Contrôle le taux d’utilisation mémoire d’un serveur ESX. 2 métriques sont renvoyés :
      +
        +
      • le taux de lecture et d’écriture du swap globale de l’ensemble des machines virtuelles (en Mb/s).
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la(les) métrique(s) « swap_* Â» est(sont) au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéesswap_in=0b/s swap_out=0b/s
      Interval/Retry(min)20/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerswaphost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      -w ou --warning(optionnel – Défaut : 0.8) Seuil warning en MB/s0.5
      -c ou --critical(optionnel – Défaut : 1) Seuil critique en MB/s1.5
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING0.8
      CRITICAL1
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      DATASTORES¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_datastoreshost
      Description
      +
      Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés par le datastore :
      +
        +
      • la latence totale en lecture et écriture (en ms).
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyées‘trl_LUN1’=0.00ms ‘twl_LUN1’=0.00ms ‘trl_LUN2’=0.00ms ‘twl_LUN2’=1.00ms
      Interval/Retry(min)5/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerdatastoreshost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      --filter-datastores(optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules)LUN1,LUN2
      -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms75
      -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms90
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING30
      CRITICAL50
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      COUNTVM¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_countvmhost
      Description
      +
      Contrôle le taux d’utilisation mémoire d’un serveur ESX. 1 métrique est remontée :
      +
        +
      • le nombre de machines virtuelles allumées.
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la métrique « count Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « count Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « count Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéescount=45
      Interval/Retry(min)20/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlercountvmhost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      -w ou --warning(optionnel – Défaut : aucunes valeurs) Seuil warning en ms10
      -c ou --critical(optionnel – Défaut : aucunes valeurs) Seuil critique en ms15
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING10
      CRITICAL15
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      HEALTH¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_healthhost
      DescriptionContrôle l’état des sondes matériels et processeurs d’un serveur ESX.
      Fonctionnement
      +
      Remonte un état selon l’état des sondes:
      +
        +
      • “Yellow” correspond à WARNING.
      • +
      • “Red” correspond à CRITICAL.
      • +
      +
      +
      +
      Métriques renvoyées 
      Interval/Retry(min)30/1
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerhealthhost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
        
        
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      MAINTENANCE¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_maintenancehost
      DescriptionContrôle le mode de maintenance d’un serveur ESX.
      Fonctionnement
        +
      • Remonte l’état « CRITICAL » si le serveur ESX est en mode de maintenance.
      • +
      +
      Métriques renvoyées 
      Interval/Retry(min)30/1
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlermaintenancehost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
        
        
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      STATUT¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_statushost
      DescriptionContrôle l’état global d’un serveur ESX.
      Fonctionnement
        +
      • Remonte l’état « CRITICAL » si le statut du serveur ESX est en « red » .
      • +
      • Remonte l’état « WARNING » si le statut du serveur ESX est en « yellow » .
      • +
      • Remonte l’état « UNKNOWN » si le statut du serveur ESX est en « gray » .
      • +
      +
      Métriques renvoyées 
      Interval/Retry(min)30/1
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerstatushost
      -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
        
        
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +
      +

      Contrôles d’une machine virtuelle¶

      +
      +

      CPU¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_cpuvm
      DescriptionContrôle le taux d’utilisation CPU d’une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs.
      Fonctionnement
        +
      • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéescpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz
      Interval/Retry(min)5/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlercpuvm
      --vmNom de la machine virtuelle cibléemyvmname
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING80
      CRITICAL90
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      MEMOIRE¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_memvm
      Description
      +
      Contrôle le taux d’utilisation mémoire d’une machine virtuelle. 6 métriques sont renvoyés :
      +
        +
      • « used Â» : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets)
      • +
      • « size Â» : la taille totale de la mémoire allouée pour la machine virtuelle (en octets)
      • +
      • « overhead Â» : la mémoire sur-alloué (en octets)
      • +
      • « ballooning Â», « shared Â» et « active Â».
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéesusage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o
      Interval/Retry(min)20/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlermemvm
      --vmNom de la machine virtuelle cibléemyvmname
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING80
      CRITICAL90
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      DATASTORES¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_datastoresvm
      Description
      +
      Contrôle le taux d’utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore :
      +
        +
      • « riops Â» : le nombre moyen d’I/O de lectures par seconde
      • +
      • « wiops Â» : le nombre moyen d’I/O d’écritures par seconde
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si une métrique est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyées‘riops_LUN1’=0.00iops ‘wiops_LUN1’=0.27iops ‘riops_LUN2’=20.00iops ‘wiops_LUN2’=100.2iops
      Interval/Retry(min)5/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerdatastoresvm
      --vmNom de la machine virtuelle cibléemyvmname
      -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms100
      -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms150
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      WARNING100
      CRITICAL150
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      VMTOOLS¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_toolsvm
      DescriptionContrôle l’état des VMTools rattachées à une machine virtuelle.
      Fonctionnement
        +
      • Remonte l’état « WARNING » si les VMTools sont ‘toolsold’.
      • +
      • Remonte l’état « CRITICAL » si les VMTools sont ‘toolsnotrunning’ ou ‘toolsnotinstalled’.
      • +
      +
      Métriques renvoyées 
      Interval/Retry(min)20/1
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlertoolsvm
      --vmNom de la machine virtuelle cibléemyvmname
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
        
        
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      SNAPSHOTS¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_snapshotvm
      DescriptionContrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle.
      Fonctionnement
      +
      L’état dépend des paramètres du plugin :
      +
        +
      • Si « –warn Â» spécifié seul : remonte un état WARNING si un snapshost est présent.
      • +
      • Si « –crit Â» spécifié seul : remonte un état CRITICAL si un snapshost est présent.
      • +
      • Si « –warn Â» et « –older XXX Â» : remonte un état WARNING si un snapshost est présent et la date de création du +snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
      • +
      • Si « –crit Â» et « –older XXX Â» : remonte un état CRITICAL si un snapshost est présent et la date de création du +snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
      • +
      +
      +
      +
      Métriques renvoyées 
      Interval/Retry(min)20/1
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlersnapshotvm
      --vmNom de la machine virtuelle cibléemyvmname
      --warn(optionnel) Permet de spécifier un état WARNING 
      --crit(optionnel) Permet de spécifier un état CRITICAL 
      --older(optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant86400 (snapshot vieux de + 1jour)
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + +
      Macro NameMacro Value
      THRESHOLD
        +
      • -warn
      • +
      +
        
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +
      +

      Contrôle d’un datastore¶

      +
      +

      USAGE¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_datastoreusage
      Description
      +
      Contrôle le taux d’utilisation d’un datastore. 2 métriques sont renvoyés :
      +
        +
      • « used Â» : l’espace occupé par le datastore (en octets)
      • +
      • « size Â» : la taille totale allouée pour le datastore (en octets)
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéesused=506574405632o;;;0;643976658944 size=643976658944o
      Interval/Retry(min)20/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerdatastore-usage
      -e ou --esx-hostNom du datastore ciblédsname
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + + + + +
      Macro NameMacro Value
      DSNAME 
      WARNING80
      CRITICAL90
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +

      DATASTORE I/O¶

      +
      +
      Fiche d’identité¶
      + ++++ + + + + + + + + + + + + + + + + + +
      Nom du plugincheck_merethis_vmware_datastorio
      Description
      +
      Contrôle le taux d’utilisation (I/O) d’un datastore. 2 métriques sont renvoyés :
      +
        +
      • « read_rate Â» : le taux d’utilisation moyen en lecture par seconde (en b/s)
      • +
      • « write_rate Â» : la taille d’utilisation moyen en écriture par seconde (en b/s)
      • +
      +
      +
      +
      Fonctionnement
        +
      • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
      • +
      • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
      • +
      • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
      • +
      +
      Métriques renvoyéesread_rate=1589248b/s write_rate=14344192b/s
      Interval/Retry(min)5/5
      +
      +
      +
      Attribut du contrôle¶
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributDescriptionExemple
      -uIndicateur à contrôlerdatastore-io
      -e ou --esx-hostNom du datastore ciblédsname
      -w ou --warning(optionnel – Défaut : 80) Seuil warning en kBps100
      -c ou --critical(optionnel – Défaut : 90) Seuil critique en kBps200
      +

      Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

      + ++++ + + + + + + + + + + + + + +
      OptionComportement
      -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
      -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      +
      +
      +
      Création d’un service et/ou modèle de service¶
      +

      Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

      +

      Définir les macros suivante :

      + ++++ + + + + + + + + + + + + + + + + +
      Macro NameMacro Value
      DSNAME 
      WARNING100
      CRITICAL150
      +
      +
      +
      Création d’une check command¶
      +

      Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

      +
      $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
      +
      +

      L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

      +
      +
      +
      +
      + + + + + + +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Installation

      +

      This Page

      + + + +
      +
      +
      + + + + + \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/genindex.html b/connectors/vmware/doc/_build/html/genindex.html new file mode 100644 index 000000000..461f46511 --- /dev/null +++ b/connectors/vmware/doc/_build/html/genindex.html @@ -0,0 +1,92 @@ + + + + + + + + + Index — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + +
      +
      +
      +
      + + +

      Index

      + +
      + +
      + + +
      +
      +
      +
      +
      + + + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/index.html b/connectors/vmware/doc/_build/html/index.html new file mode 100644 index 000000000..7bce10796 --- /dev/null +++ b/connectors/vmware/doc/_build/html/index.html @@ -0,0 +1,133 @@ + + + + + + + + Welcome to Centreon ESXD’s documentation! — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + +
      + +
      +
      +

      Table Of Contents

      + + +

      Next topic

      +

      Installation

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/installation/index.html b/connectors/vmware/doc/_build/html/installation/index.html new file mode 100644 index 000000000..9b05d179c --- /dev/null +++ b/connectors/vmware/doc/_build/html/installation/index.html @@ -0,0 +1,314 @@ + + + + + + + + Installation — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Installation¶

      +
      +

      Pré-Requis¶

      +
      +

      Préconisations logicielles¶

      +

      Le connecteur “centreon-esxd” est testé et validé sur des environnements Linux. +L’installation sur d’autres environnements n’est pas exclu mais non présenté dans ce document (Solaris, Windows, ...).

      + ++++ + + + + + + + + + + + + + + + + +
      LogicielsVersion minimum
      VMWare SDK Perl5.0
      Perl5.8
      centreon-esxd1.3
      +
      +
      +

      Préconisations matérielles¶

      +

      Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n’effectue aucunes vérifications. Les ressources minimales sont de :

      +
        +
      • mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle).
      • +
      • CPU : même pré-requis que pour le serveur de collecte.
      • +
      +
      +
      +
      +

      Installation de centreon-esxd - Environnement centos/rhel 5¶

      +
      +

      Installation du SDK Perl VMWare¶

      +

      Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l’installer. Pour cela nous allons commencer par installer CPAN qui est le nom d’un module Perl qui rend aisés le téléchargement, l’installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN.

      +

      Installer les pré-requis CPAN:

      +
      root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel
      +root # yum install perl-XML-LibXML perl-Crypt-SSLeay
      +
      +root # cpan install Class::MethodMaker
      +root # cpan install LWP
      +root # cpan install Net::SSLeay
      +root # cpan install LWP::Protocol::https
      +root # cpan install SOAP::Lite
      +
      +root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
      +root # tar zxvf UUID-0.04.tar.gz
      +root # cd UUID-0.04
      +root # perl Makefile.PL
      +root # make && make install
      +
      +
      +

      Nous avons notre environnement prêt pour l’installation du SDK VMWare.

      +

      Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (SDK VMWare).

      +

      Installer le SDK Perl VMWare:

      +
      root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
      +root # cd vmware-vsphere-cli-distrib
      +root # perl Makefile.pl
      +root # make && make install
      +
      +
      +
      +
      +

      Installation de modules complémentaires¶

      +

      Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd :

      +

      Pour envoyer les logs au daemon « syslog Â», il est nécessaire d’installer le module « Unix::Syslog »:

      +
      root # cpan install Unix::Syslog
      +
      +
      +

      Pour vérifier la date des snapshots d’une machine virtuelle, il est nécessaire d’installer le module « DateTime::Format::ISO8601 Â» ( ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl Â». Cette mise à jour est très risqué ):

      +
      root # cpan install DateTime
      +root # cpan install DateTime::Format::ISO8601
      +root # o conf make /usr/bin/make
      +root # o conf commit
      +
      +
      +

      Ensuite redémarrer votre système.

      +
      +
      +

      Installation de centreon-esxd¶

      +

      Télécharger l’archive de « centreon-esxd Â».

      +

      Installer les fichiers:

      +
      root # tar zxvf centreon-esxd-1.X.tar.gz
      +root # cd centreon-esxd-1.X
      +root # cp centreon_esxd /usr/bin/
      +
      +root # mkdir -p /etc/centreon
      +root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
      +root # cp centreon_esxd-init /etc/init.d/centreon_esxd
      +
      +root # mkdir -p /usr/share/centreon/lib/centreon-esxd
      +root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
      +
      +
      +

      Activer le daemon « centreon-esxd Â» au démarrage:

      +
      root # chkconfig --level 2345 centreon_esxd on
      +
      +
      +

      Le plugin « nagios Â» correspond au fichier « centreon_esx_client.pl Â».

      +
      +
      +
      +

      Installation de centreon-esxd - Environnement centos/rhel 6¶

      +
      +

      Installation du sdk Perl VMWare¶

      +

      Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement.

      +

      Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l’installer. Pour cela nous allons commencer par installer CPAN qui est le nom d’un module Perl qui rend aisés le téléchargement, l’installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN.

      +

      Installer les pré-requis CPAN:

      +
      root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel
      +root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite
      +
      +root # cpan install Test::More
      +root # cpan install LWP
      +root # cpan install Net::SSLeay
      +root # cpan install LWP::Protocol::https
      +
      +root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
      +root # tar zxvf UUID-0.04.tar.gz
      +root # cd UUID-0.04
      +root # perl Makefile.PL
      +root # make && make install
      +
      +
      +

      Nous avons notre environnement prêt pour l’installation du SDK VMWare.

      +

      Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (SDK VMWare)

      +

      Installer le SDK Perl VMWare:

      +
      root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
      +root # cd vmware-vsphere-cli-distrib
      +root # perl Makefile.pl
      +root # make && make install
      +
      +
      +
      +
      +

      Installation de modules complémentaires¶

      +

      Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd :

      +

      Pour envoyer les logs au daemon « syslog Â», il est nécessaire d’installer le module « Unix::Syslog »:

      +
      root # cpan install Unix::Syslog
      +
      +
      +

      Pour vérifier la date des snapshots d’une machine virtuelle, il est nécessaire d’installer le module « DateTime::Format::ISO8601 Â» ( ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl Â». Cette mise à jour est très risqué ):

      +
      root # cpan install DateTime
      +root # cpan install DateTime::Format::ISO8601
      +root # o conf make /usr/bin/make
      +root # o conf commit
      +
      +
      +

      Ensuite redémarrer votre système.

      +
      +
      +

      Installation de centreon-esxd¶

      +

      Télécharger l’archive de « centreon-esxd Â».

      +

      Installer les fichiers:

      +
      root # tar zxvf centreon-esxd-1.X.tar.gz
      +root # cd centreon-esxd-1.X
      +root # cp centreon_esxd /usr/bin/
      +
      +root # mkdir -p /etc/centreon
      +root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
      +root # cp centreon_esxd-init /etc/init.d/centreon_esxd
      +
      +root # mkdir -p /usr/share/centreon/lib/centreon-esxd
      +root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
      +
      +
      +

      Activer le daemon « centreon-esxd Â» au démarrage:

      +
      root # chkconfig --level 2345 centreon_esxd on
      +
      +
      +

      Le plugin « nagios Â» correspond au fichier « centreon_esx_client.pl Â».

      +
      +
      +
      + + +
      +
      +
      + +
      +
      + + + + \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/objects.inv b/connectors/vmware/doc/_build/html/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..6b9e7d70341d5f6891429e463885b3a060ed17b1 GIT binary patch literal 209 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~KjbN*1L8MO}j< zT!0c`5JgrBhI$4-Zb(L|LQ!gNVrE`SYLP;InnFoNX0bwAW=^UCkWS9eEhtJYE>2BR zC@s#+OIN7M$xPDYs + + + + + + + Search — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +

      Search

      +
      + +

      + Please activate JavaScript to enable the search + functionality. +

      +
      +

      + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

      +
      + + + +
      + +
      + +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/connectors/vmware/doc/_build/html/searchindex.js b/connectors/vmware/doc/_build/html/searchindex.js new file mode 100644 index 000000000..6a665ac86 --- /dev/null +++ b/connectors/vmware/doc/_build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{"2iop":2,code:[],check_merethis_vmware_datastorio:2,trl_lun2:2,librairi:2,global:[1,2],troi:2,yellow:2,"\u00e9clat\u00e9":2,fourni:2,row:[],indicateur:2,"27iop":2,init:1,"surallou\u00e9":2,aux:2,valeur:2,"d\u00e9j\u00e0":2,sond:2,"valid\u00e9":1,"22743040o":2,sont:[1,2],garder:2,check_merethis_vmware_nethost:2,level:1,"d\u00e9marrag":1,servic:[],x86_64:1,visualis:2,"362747904o":2,"derni\u00e8r":1,direct:2,syslog:[1,2],second:2,pass:2,port:2,vmware:[],supervis:2,"_hostvcnam":2,section:[],quelqu:2,statushost:2,riops_lun1:2,communiqu:2,version:1,sur:[1,2],peuvent:[1,2],net:1,cela:[1,2],"charg\u00e9":2,"contr\u00f4ler":2,voici:2,snapshost:2,bodi:[],solari:1,"fonctionnalit\u00e9":1,modifi:2,valu:2,"m\u00eame":1,"tr\u00e8":1,search:[0,1],"v\u00e9rific":1,"r\u00e9cup\u00e8r":2,beaucoup:1,host:2,datetim:1,action:2,que:[1,2],environn:[],"risqu\u00e9":1,modul:[],souhaitez:[1,2],unix:[1,2],instal:[],total:2,"1773761536o":2,commun:2,lwp:1,pourcentag:2,perl:[],latenc:2,overhead:2,rhel:[],vcenter:2,type:2,more:1,ensuit:[1,2],riop:2,check_merethis_vmware_cpuhost:2,log_daemon:2,filtrer:2,check_merethis_vmware_datastoresvm:2,iso8601:1,warn:2,twl_lun2:2,twl_lun1:2,moin:2,cach:2,"rattach\u00e9":2,augment:1,car:2,uniqu:2,pour:[1,2],minimum:1,taux:2,nagio:1,root:1,"506574405632o":2,tar:1,requi:[],share:[1,2],check_merethis_vmware_swaphost:2,templat:2,critic:2,unzip:1,check_merethis_vmware_healthhost:2,"r\u00e9pons":2,traffic_out:2,suivant:2,gcc:1,refresh_keeper_sess:2,"totalit\u00e9":2,rapport:2,write:[],toolsnotinstal:2,optimal:2,xxxx:2,swap_in:2,mac:2,attent:2,mai:[1,2],datastoresvm:2,datastor:[],"remont\u00e9":2,souci:2,permet:2,light:2,timeout_kil:2,correspond:[1,2],allon:1,issu:2,inform:2,ensembl:2,make:1,"m\u00e9moir":[1,2],"d\u00e9faut":[1,2],offici:[],peut:[1,2],"00mhz":2,afin:2,"h\u00e9bergeant":2,kbp:2,jnh:1,"r\u00e9colter":2,"_servicethreshold":2,uuid:1,window:1,"\u00e9critur":2,memhost:2,nom:[1,2],non:1,"syst\u00e8m":[1,2],handl:2,dan:1,taill:2,devel:1,"\u00e9galement":2,effectu:[1,2],autr:1,optionnel:2,nou:1,"1jour":2,"bas\u00e9":2,critiqu:2,name:2,aucun:[1,2],temps_cour:2,"install\u00e9":1,check_merethis_vmware_datastoreusag:2,timeout:2,champ:2,cett:[1,2],espac:2,"cr\u00e9er":2,connect:2,"r\u00e9seau":2,distrib:1,our:2,"probl\u00e8m":2,variabl:2,respectiv:2,mettr:1,"nomm\u00e9":2,content:0,"\u00e9cout":2,traffic_in:2,centreon_esxd:[1,2],red:2,serveur:[1,2],"contr\u00f4l":1,check_merethis_vmware_maintenancehost:2,e2fsprog:1,qui:[1,2],org:1,selon:2,contient:2,libuuid:1,openssl:1,filter:2,liaison:2,yum:1,unknown:2,processeur:2,"r\u00e9sultat":2,"pr\u00e9sent\u00e9":1,check_merethis_vmware_countvmhost:2,mise:1,"pr\u00e9":[],votr:1,affich:2,donc:1,"indiqu\u00e9":2,crit:2,virtualcent:2,tou:2,ont:2,size:2,fonctionn:[],"_hostesxdport":2,mkdir:1,trl_lun1:2,nethost:2,"final":2,shell:[],option:2,"poss\u00e8d":2,cpu2:2,cpu3:2,specifi:2,cpu1:2,"d\u00e9pend":[1,2],date:[1,2],centreon_esx_cli:[1,2],ssl3_get_record:2,"00iop":2,older:2,wiops_lun2:2,wiops_lun1:2,timeout_vspher:2,ressourc:[1,2],sera:2,"red\u00e9marr":1,cpu_total_mhz:2,"acc\u00e8":2,aussi:2,myvmnam:2,"56196403200o":2,wiop:2,jour:1,lib:[1,2],min:2,hostvcnam:2,"d\u00e9connexion":2,libpath:2,fonction:1,deux:2,soap:[1,2],simplifi:2,macro:2,"sp\u00e9cifier":2,index:0,usernam:2,"configur\u00e9":2,plat:2,doit:2,dessu:2,maintenancehost:2,cpu0:2,"v\u00e9rifier":1,toolsnotrun:2,"class":1,url:2,request:2,snapshot:1,"_servicedsnam":2,"68705865728o":2,"\u00e9tat":2,vcname:2,"n\u00e9cessair":[1,2],"cr\u00e9\u00e9":2,text:[],session:2,threshold:2,identifi:2,trop:2,retrouv:2,xml:1,fichier:[1,2],menu:2,activ:[1,2],"cr\u00e9ant":2,"70148096o":2,"diff\u00e9rent":2,"s\u00e9par\u00e9":2,yml:[],count:2,cpuvm:2,ssl:2,mainten:1,"pr\u00eat":1,"t\u00e9l\u00e9chargement":1,vsphere_serv:2,"172032b":2,"2147483648o":2,snapshotvm:2,grai:2,bad:2,write_r:2,"\u00e9vite":2,"caract\u00e8r":2,swap_out:2,riops_lun2:2,"643976658944o":2,"_servicecrit":2,"recommand\u00e9":2,fail:2,sen:2,xxxxx:2,sorti:2,nombr:[1,2],vont:2,"_servicewarn":2,attribut:[],parent:2,check_merethis_vmware_memhost:2,officiel:1,comm:2,avon:1,cli:1,plugin:[1,2],"sp\u00e9cifi\u00e9":2,etc:[1,2],erreur:2,rend:1,login:2,"allou\u00e9":2,"d\u00e9conseill\u00e9":2,makefil:1,"d\u00e9finit":2,perfdata:2,"d\u00e9finir":2,linux:1,connexion:2,aller:2,json:[],"pr\u00e9sent":2,difficil:1,datastoreshost:2,cpu_tot:2,xxx:2,demand:[1,2],viperltoolkit:[],toolsvm:2,"entr\u00e9":2,"ais\u00e9":1,"_hostesxdhost":2,error:2,"1408f119":2,stdout:2,envoy:1,expat:1,"4561920o":2,"allum\u00e9":2,"00m":2,vou:[1,2],libxml:1,archiv:1,cento:[],conf:1,chkconfig:1,situ:2,par:[1,2],develop:[],log_crit:2,author:1,perform:2,balloon:2,memvm:2,"pr\u00e9senc":2,"ex\u00e9cut":2,"imp\u00e9rativ":2,traiter:2,grand:2,lite:1,http:[1,2],ouvr:2,nic:2,nicnam:2,vieux:2,moyen:2,"h\u00f4te":[],com:[],notr:1,"r\u00e9cup\u00e9rer":2,traffic_:2,client:2,command:[],titl:[],san:[1,2],programm:2,"g\u00e9n\u00e8re":2,protocol:[1,2],physiqu:2,tcp:2,processu:2,ayant:2,connecteur:1,bit:1,"renvoy\u00e9":2,site:1,virgul:2,toolsold:2,exempl:2,"cibl\u00e9":2,bloc:[],log_facil:2,enfin:2,check_merethis_vmware_snapshotvm:2,adress:2,esxdhost:2,bin:1,xxxxxx:2,format:1,read:2,mot:2,cpan:[],remont:2,check_merethis_vmware_datastoreshost:2,healthhost:2,password:2,daemon:[1,2],header:[],fournir:2,"d\u00e9fini":2,dsname:2,noth:2,collect:1,"pr\u00e9alabl":2,page:0,"r\u00f4le":2,www:[],besoin:2,swap_:2,interv:2,seuil:2,"14344192b":2,log_mod:2,hostesxdhost:2,bloqu:2,"n\u00e9cessit":2,ouvert:2,tmp:2,est:[1,2],swaphost:2,octet:2,esx:[],retri:2,avoir:2,minimal:1,machin:1,plu:2,sensibl:1,ancien:2,usag:[],virtuel:1,"test\u00e9":1,wget:1,"\u00eatre":[1,2],column:[],commit:1,"donn\u00e9":2,zxvf:1,routin:2,read_rat:2,vsphere:[1,2],son:[1,2],lier:2,"archiv\u00e9":1,sou:2,retourn:2,lieu:2,mymeta:[],testvc:2,log:[1,2],plusieur:2,support:[],logiciel:[],lor:2,esx1:2,interfac:2,comport:2,"1589248b":2,methodmak:1,usr:[1,2],lun2:2,lun1:2,pleinement:2,form:2,link:[],cpuhost:2,sdk:[],info:2,vive:1,temp:2,possibl:2,"default":2,avec:2,record:2,"cha\u00een":2,notam:2,vmnic0:2,"s\u00e9rie":2,user1:2,certain:1,utilis:[1,2],decrypt:2,lectur:2,"m\u00e9triqu":2,file:2,dessou:2,"mod\u00e8l":[],hostesxdport:2,commenc:1,"occup\u00e9":2,courant:2,check_merethis_vmware_statushost:2,crypt:1,seul:2,"_servicenicnam":2,normal:2,viell:2,test:[1,2],snaphost:2,architectur:[1,2],countvmhost:2,check_merethis_vmware_toolsvm:2,cpu0_mhz:2,hostaddress:2,"param\u00e8tr":2,check_merethis_vmware_cpuvm:2,lanc:2,niveau:2,exclu:1,ssleai:1,descript:2,check_merethis_vmware_memvm:2,"598016b":2,esxdport:2,"t\u00e9l\u00e9charger":1,cpu:1},objtypes:{},objnames:{},filenames:["index","installation/index","exploitation/index"],titles:["Welcome to Centreon ESXD’s documentation!","Installation","Exploitation"],objects:{},titleterms:{configur:2,modul:1,requi:1,"pr\u00e9":1,"contr\u00f4l":2,indic:0,exploit:2,cento:1,tabl:0,instal:1,"cr\u00e9ation":2,connecteur:2,check:2,vmware:[1,2],centreon:[0,1,2],reseau:2,welcom:0,"mod\u00e8l":2,titl:[],section:[],"mat\u00e9riel":1,logiciel:1,perl:1,health:2,rhel:1,optimisationd:[],document:0,memoir:2,attribut:2,machin:2,swap:2,statut:2,dan:2,usag:2,"identit\u00e9":2,"pr\u00e9conis":1,"h\u00f4te":2,"g\u00e9n\u00e9riqu":2,mainten:2,cpan:[],datastor:2,fonctionn:2,countvm:2,sdk:1,vmtool:2,esxd:[0,1,2],"compl\u00e9mentair":1,optimis:2,command:2,troubleshoot:2,"g\u00e9n\u00e9raux":2,list:2,virtuel:2,"pr\u00e9sentat":2,princip:2,snapshot:2,mode:2,esx:2,fich:2,servic:2,cpu:2,environn:1}}) \ No newline at end of file diff --git a/connectors/vmware/doc/conf.py b/connectors/vmware/doc/conf.py new file mode 100644 index 000000000..e9144e890 --- /dev/null +++ b/connectors/vmware/doc/conf.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# +# Centreon ESXD documentation build configuration file, created by +# sphinx-quickstart on Mon Apr 22 11:17:38 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Centreon ESXD' +copyright = u'2013, Merethis' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '1.0' +# The full version, including alpha/beta/rc tags. +release = '1.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'CentreonESXDdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'CentreonESXD.tex', u'Centreon ESXD Documentation', + u'Merethis', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'centreonesxd', u'Centreon ESXD Documentation', + [u'Merethis'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'CentreonESXD', u'Centreon ESXD Documentation', + u'Merethis', 'CentreonESXD', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/connectors/vmware/doc/exploitation/index.rst b/connectors/vmware/doc/exploitation/index.rst new file mode 100644 index 000000000..c5657eb15 --- /dev/null +++ b/connectors/vmware/doc/exploitation/index.rst @@ -0,0 +1,1384 @@ +============ +Exploitation +============ + +Présentation de Centreon-esxd +----------------------------- + +Principes Généraux +`````````````````` + +Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. + +Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : + +*« handle-client »*: + *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + +Voici le fonctionnement : + +- Un client se connecte. +- Le client demande un indicateur de supervision sur un VirtualCenter. +- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». +- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». +- Le processus « handle-client » fourni la réponse au client. + +*« handle-vsphere-xxxx »*: + *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* + +Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. + +Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. + +Voici un exemple d'architecture éclaté : + +.. image:: ../images/archi.png + +Mode de fonctionnement +`````````````````````` +Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). + +Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. + +Configuration du connecteur +``````````````````````````` +Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: + + 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', + 'password' => 'XXXXXX'} + 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"; + +La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. + +La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». + +Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. + +Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. + + +Optimisation de la configuration dans Centreon +---------------------------------------------- + +Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. + +Ce connecteur permet la définition de trois modèles d'hôtes : + +- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. +- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. +- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») + +Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. + ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | +| | | | ++====================+===================================================================+================================================================+ +| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ + +Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». + + +Création d'un modèle d'hôte VMWare générique +```````````````````````````````````````````` + +Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». + +Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. + +Définir les macros suivante : + ++---------------------+-------------------------------------------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+===================================================================+ +| ESXDHOST | Exemple: 10.30.10.30 | ++---------------------+-------------------------------------------------------------------+ +| ESXDPORT | 5700 (port par défaut) | ++---------------------+-------------------------------------------------------------------+ +| VCNAME | default | ++---------------------+-------------------------------------------------------------------+ + +Troubleshooting +``````````````` + +Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: + + ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... + +Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. + +Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. + + +Liste des contrôles +------------------- + +Contrôles ESX +````````````` +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++===========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuhost | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | +| | - le taux d'utilisation mémoire (en octets), | +| | - la taille totale de la mémoire (en octets), | +| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memhost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +RESEAU +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_nethost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux d'utilisation en entrée et sortie (en b/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | nethost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| NICNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +SWAP +'''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_swaphost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | swaphost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 0.8 | ++---------------------+--------------------------------+ +| CRITICAL | 1 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreshost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | +| | - la latence totale en lecture et écriture (en ms). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++============================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoreshost | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 30 | ++---------------------+--------------------------------+ +| CRITICAL | 50 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +COUNTVM +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_countvmhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | +| | - le nombre de machines virtuelles allumées. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | count=45 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | countvmhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 10 | ++---------------------+--------------------------------+ +| CRITICAL | 15 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +HEALTH +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_healthhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | Remonte un état selon l'état des sondes: | +| | - "Yellow" correspond à WARNING. | +| | - "Red" correspond à CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | healthhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MAINTENANCE +''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_maintenancehost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | maintenancehost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +STATUT +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_statushost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état global d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | +| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | +| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | statushost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôles d'une machine virtuelle +````````````````````````````````` + +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuvm | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | +| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | +| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | +| | - « overhead » : la mémoire sur-alloué (en octets) | +| | - « ballooning », « shared » et « active ». | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoresvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | +| | - « riops » : le nombre moyen d'I/O de lectures par seconde | +| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoresvm | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +VMTOOLS +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_toolsvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | +| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | toolsvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +SNAPSHOTS +''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_snapshotvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | L'état dépend des paramètres du plugin : | +| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | +| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | +| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | +| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++====================+==========================================================================================+================================================================+ +| -u | Indicateur à contrôler | snapshotvm | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| THRESHOLD | - -warn | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôle d'un datastore +``````````````````````` + +USAGE +''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreusage | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | +| | - « used » : l'espace occupé par le datastore (en octets) | +| | - « size » : la taille totale allouée pour le datastore (en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-usage | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORE I/O +''''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastorio | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | +| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | +| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-io | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + diff --git a/connectors/vmware/doc/images/archi.png b/connectors/vmware/doc/images/archi.png new file mode 100644 index 0000000000000000000000000000000000000000..82dca91fec4159d8be96155e65412aa0fd645059 GIT binary patch literal 29775 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 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc/index.rst b/connectors/vmware/doc/index.rst new file mode 100644 index 000000000..8f840209e --- /dev/null +++ b/connectors/vmware/doc/index.rst @@ -0,0 +1,24 @@ +.. Centreon ESXD documentation master file, created by + sphinx-quickstart on Mon Apr 22 11:17:38 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Centreon ESXD's documentation! +========================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + installation/index + exploitation/index + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/connectors/vmware/doc/installation/index.rst b/connectors/vmware/doc/installation/index.rst new file mode 100644 index 000000000..3534d2c3c --- /dev/null +++ b/connectors/vmware/doc/installation/index.rst @@ -0,0 +1,191 @@ +============ +Installation +============ + +Pré-Requis +========== + +Préconisations logicielles +`````````````````````````` + +Le connecteur "centreon-esxd" est testé et validé sur des environnements Linux. +L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Solaris, Windows, ...). + +==================== ===================== +Logiciels Version minimum +==================== ===================== +VMWare SDK Perl 5.0 +Perl 5.8 +centreon-esxd 1.3 +==================== ===================== + +Préconisations matérielles +`````````````````````````` + +Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n'effectue aucunes vérifications. Les ressources minimales sont de : + +* mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). + +* CPU : même pré-requis que pour le serveur de collecte. + +Installation de centreon-esxd - Environnement centos/rhel 5 +=========================================================== + +Installation du SDK Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay + + root # cpan install Class::MethodMaker + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + root # cpan install SOAP::Lite + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +Nous avons notre environnement prêt pour l'installation du SDK VMWare. + +Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_). + +Installer le SDK Perl VMWare:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Installation de modules complémentaires +``````````````````````````````````````` + +Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : + +Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: + + root # cpan install Unix::Syslog + +Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Ensuite redémarrer votre système. + +Installation de centreon-esxd +````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* + +Installation de centreon-esxd - Environnement centos/rhel 6 +=========================================================== + +Installation du sdk Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite + + root # cpan install Test::More + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +Nous avons notre environnement prêt pour l'installation du SDK VMWare. + +Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_) + +Installer le SDK Perl VMWare:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Installation de modules complémentaires +``````````````````````````````````````` + +Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : + +Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: + + root # cpan install Unix::Syslog + +Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Ensuite redémarrer votre système. + +Installation de centreon-esxd +````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* + + From 5534b8c415eb6cb3af4e9a8e218d3ddb0421878b Mon Sep 17 00:00:00 2001 From: Vincent Varlet Date: Thu, 16 May 2013 15:58:50 +0000 Subject: [PATCH 037/447] Start Doc EN git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@55 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/doc-en/Makefile | 177 ++ .../doc-en/_build/doctrees/environment.pickle | Bin 0 -> 43441 bytes .../doctrees/exploitation/index.doctree | Bin 0 -> 341484 bytes .../doc-en/_build/doctrees/index.doctree | Bin 0 -> 5558 bytes .../doctrees/installation/index.doctree | Bin 0 -> 31121 bytes .../vmware/doc-en/_build/html/.buildinfo | 4 + .../doc-en/_build/html/_images/archi.png | Bin 0 -> 29775 bytes .../html/_sources/exploitation/index.txt | 1384 ++++++++++ .../doc-en/_build/html/_sources/index.txt | 24 + .../html/_sources/installation/index.txt | 191 ++ .../_build/html/_static/ajax-loader.gif | Bin 0 -> 673 bytes .../doc-en/_build/html/_static/basic.css | 540 ++++ .../_build/html/_static/comment-bright.png | Bin 0 -> 3500 bytes .../_build/html/_static/comment-close.png | Bin 0 -> 3578 bytes .../doc-en/_build/html/_static/comment.png | Bin 0 -> 3445 bytes .../doc-en/_build/html/_static/default.css | 256 ++ .../doc-en/_build/html/_static/doctools.js | 235 ++ .../_build/html/_static/down-pressed.png | Bin 0 -> 368 bytes .../doc-en/_build/html/_static/down.png | Bin 0 -> 363 bytes .../doc-en/_build/html/_static/file.png | Bin 0 -> 392 bytes .../doc-en/_build/html/_static/jquery.js | 4 + .../doc-en/_build/html/_static/minus.png | Bin 0 -> 199 bytes .../doc-en/_build/html/_static/plus.png | Bin 0 -> 199 bytes .../doc-en/_build/html/_static/pygments.css | 62 + .../doc-en/_build/html/_static/searchtools.js | 622 +++++ .../doc-en/_build/html/_static/sidebar.js | 159 ++ .../doc-en/_build/html/_static/underscore.js | 31 + .../doc-en/_build/html/_static/up-pressed.png | Bin 0 -> 372 bytes .../vmware/doc-en/_build/html/_static/up.png | Bin 0 -> 363 bytes .../doc-en/_build/html/_static/websupport.js | 808 ++++++ .../_build/html/exploitation/index.html | 2376 +++++++++++++++++ .../vmware/doc-en/_build/html/genindex.html | 92 + .../vmware/doc-en/_build/html/index.html | 133 + .../_build/html/installation/index.html | 314 +++ .../vmware/doc-en/_build/html/objects.inv | Bin 0 -> 209 bytes .../vmware/doc-en/_build/html/search.html | 99 + .../vmware/doc-en/_build/html/searchindex.js | 1 + connectors/vmware/doc-en/conf.py | 248 ++ .../vmware/doc-en/exploitation/index.rst | 1384 ++++++++++ connectors/vmware/doc-en/images/archi.png | Bin 0 -> 29775 bytes connectors/vmware/doc-en/index.rst | 24 + .../vmware/doc-en/installation/index.rst | 184 ++ 42 files changed, 9352 insertions(+) create mode 100644 connectors/vmware/doc-en/Makefile create mode 100644 connectors/vmware/doc-en/_build/doctrees/environment.pickle create mode 100644 connectors/vmware/doc-en/_build/doctrees/exploitation/index.doctree create mode 100644 connectors/vmware/doc-en/_build/doctrees/index.doctree create mode 100644 connectors/vmware/doc-en/_build/doctrees/installation/index.doctree create mode 100644 connectors/vmware/doc-en/_build/html/.buildinfo create mode 100644 connectors/vmware/doc-en/_build/html/_images/archi.png create mode 100644 connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt create mode 100644 connectors/vmware/doc-en/_build/html/_sources/index.txt create mode 100644 connectors/vmware/doc-en/_build/html/_sources/installation/index.txt create mode 100644 connectors/vmware/doc-en/_build/html/_static/ajax-loader.gif create mode 100644 connectors/vmware/doc-en/_build/html/_static/basic.css create mode 100644 connectors/vmware/doc-en/_build/html/_static/comment-bright.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/comment-close.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/comment.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/default.css create mode 100644 connectors/vmware/doc-en/_build/html/_static/doctools.js create mode 100644 connectors/vmware/doc-en/_build/html/_static/down-pressed.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/down.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/file.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/jquery.js create mode 100644 connectors/vmware/doc-en/_build/html/_static/minus.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/plus.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/pygments.css create mode 100644 connectors/vmware/doc-en/_build/html/_static/searchtools.js create mode 100644 connectors/vmware/doc-en/_build/html/_static/sidebar.js create mode 100644 connectors/vmware/doc-en/_build/html/_static/underscore.js create mode 100644 connectors/vmware/doc-en/_build/html/_static/up-pressed.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/up.png create mode 100644 connectors/vmware/doc-en/_build/html/_static/websupport.js create mode 100644 connectors/vmware/doc-en/_build/html/exploitation/index.html create mode 100644 connectors/vmware/doc-en/_build/html/genindex.html create mode 100644 connectors/vmware/doc-en/_build/html/index.html create mode 100644 connectors/vmware/doc-en/_build/html/installation/index.html create mode 100644 connectors/vmware/doc-en/_build/html/objects.inv create mode 100644 connectors/vmware/doc-en/_build/html/search.html create mode 100644 connectors/vmware/doc-en/_build/html/searchindex.js create mode 100644 connectors/vmware/doc-en/conf.py create mode 100644 connectors/vmware/doc-en/exploitation/index.rst create mode 100644 connectors/vmware/doc-en/images/archi.png create mode 100644 connectors/vmware/doc-en/index.rst create mode 100644 connectors/vmware/doc-en/installation/index.rst diff --git a/connectors/vmware/doc-en/Makefile b/connectors/vmware/doc-en/Makefile new file mode 100644 index 000000000..2370a79c0 --- /dev/null +++ b/connectors/vmware/doc-en/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CentreonESXD.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CentreonESXD.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/CentreonESXD" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CentreonESXD" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/connectors/vmware/doc-en/_build/doctrees/environment.pickle b/connectors/vmware/doc-en/_build/doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..22474718113e27fd68404a8b0bec9516aeb1207a GIT binary patch literal 43441 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 @FVtA4N)u`}jcjRX9f{I`+cytEA*OL-dG2r6 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

      9{h2h~F;9n>s36#Fou4+B9-Yr#>{ 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 E2V%GDcK`qY literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/doctrees/index.doctree b/connectors/vmware/doc-en/_build/doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..62710a3d7f8535f68e49ca783f066598b558d2e8 GIT binary patch literal 5558 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 K9`IWq%={nn1=#-p literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/.buildinfo b/connectors/vmware/doc-en/_build/html/.buildinfo new file mode 100644 index 000000000..cd98838b0 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 5c34505a03d196bacf5235352ea2ec0d +tags: a205e9ed8462ae86fdd2f73488852ba9 diff --git a/connectors/vmware/doc-en/_build/html/_images/archi.png b/connectors/vmware/doc-en/_build/html/_images/archi.png new file mode 100644 index 0000000000000000000000000000000000000000..82dca91fec4159d8be96155e65412aa0fd645059 GIT binary patch literal 29775 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 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt new file mode 100644 index 000000000..c5657eb15 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt @@ -0,0 +1,1384 @@ +============ +Exploitation +============ + +Présentation de Centreon-esxd +----------------------------- + +Principes Généraux +`````````````````` + +Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. + +Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : + +*« handle-client »*: + *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + +Voici le fonctionnement : + +- Un client se connecte. +- Le client demande un indicateur de supervision sur un VirtualCenter. +- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». +- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». +- Le processus « handle-client » fourni la réponse au client. + +*« handle-vsphere-xxxx »*: + *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* + +Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. + +Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. + +Voici un exemple d'architecture éclaté : + +.. image:: ../images/archi.png + +Mode de fonctionnement +`````````````````````` +Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). + +Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. + +Configuration du connecteur +``````````````````````````` +Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: + + 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', + 'password' => 'XXXXXX'} + 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"; + +La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. + +La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». + +Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. + +Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. + + +Optimisation de la configuration dans Centreon +---------------------------------------------- + +Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. + +Ce connecteur permet la définition de trois modèles d'hôtes : + +- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. +- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. +- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») + +Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. + ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | +| | | | ++====================+===================================================================+================================================================+ +| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ + +Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». + + +Création d'un modèle d'hôte VMWare générique +```````````````````````````````````````````` + +Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». + +Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. + +Définir les macros suivante : + ++---------------------+-------------------------------------------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+===================================================================+ +| ESXDHOST | Exemple: 10.30.10.30 | ++---------------------+-------------------------------------------------------------------+ +| ESXDPORT | 5700 (port par défaut) | ++---------------------+-------------------------------------------------------------------+ +| VCNAME | default | ++---------------------+-------------------------------------------------------------------+ + +Troubleshooting +``````````````` + +Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: + + ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... + +Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. + +Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. + + +Liste des contrôles +------------------- + +Contrôles ESX +````````````` +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++===========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuhost | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | +| | - le taux d'utilisation mémoire (en octets), | +| | - la taille totale de la mémoire (en octets), | +| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memhost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +RESEAU +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_nethost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux d'utilisation en entrée et sortie (en b/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | nethost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| NICNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +SWAP +'''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_swaphost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | swaphost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 0.8 | ++---------------------+--------------------------------+ +| CRITICAL | 1 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreshost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | +| | - la latence totale en lecture et écriture (en ms). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++============================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoreshost | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 30 | ++---------------------+--------------------------------+ +| CRITICAL | 50 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +COUNTVM +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_countvmhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | +| | - le nombre de machines virtuelles allumées. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | count=45 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | countvmhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 10 | ++---------------------+--------------------------------+ +| CRITICAL | 15 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +HEALTH +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_healthhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | Remonte un état selon l'état des sondes: | +| | - "Yellow" correspond à WARNING. | +| | - "Red" correspond à CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | healthhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MAINTENANCE +''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_maintenancehost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | maintenancehost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +STATUT +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_statushost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état global d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | +| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | +| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | statushost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôles d'une machine virtuelle +````````````````````````````````` + +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuvm | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | +| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | +| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | +| | - « overhead » : la mémoire sur-alloué (en octets) | +| | - « ballooning », « shared » et « active ». | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoresvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | +| | - « riops » : le nombre moyen d'I/O de lectures par seconde | +| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoresvm | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +VMTOOLS +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_toolsvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | +| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | toolsvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +SNAPSHOTS +''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_snapshotvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | L'état dépend des paramètres du plugin : | +| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | +| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | +| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | +| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++====================+==========================================================================================+================================================================+ +| -u | Indicateur à contrôler | snapshotvm | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| THRESHOLD | - -warn | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôle d'un datastore +``````````````````````` + +USAGE +''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreusage | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | +| | - « used » : l'espace occupé par le datastore (en octets) | +| | - « size » : la taille totale allouée pour le datastore (en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-usage | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORE I/O +''''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastorio | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | +| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | +| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-io | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + diff --git a/connectors/vmware/doc-en/_build/html/_sources/index.txt b/connectors/vmware/doc-en/_build/html/_sources/index.txt new file mode 100644 index 000000000..8f840209e --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_sources/index.txt @@ -0,0 +1,24 @@ +.. Centreon ESXD documentation master file, created by + sphinx-quickstart on Mon Apr 22 11:17:38 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Centreon ESXD's documentation! +========================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + installation/index + exploitation/index + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt b/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt new file mode 100644 index 000000000..3534d2c3c --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt @@ -0,0 +1,191 @@ +============ +Installation +============ + +Pré-Requis +========== + +Préconisations logicielles +`````````````````````````` + +Le connecteur "centreon-esxd" est testé et validé sur des environnements Linux. +L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Solaris, Windows, ...). + +==================== ===================== +Logiciels Version minimum +==================== ===================== +VMWare SDK Perl 5.0 +Perl 5.8 +centreon-esxd 1.3 +==================== ===================== + +Préconisations matérielles +`````````````````````````` + +Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n'effectue aucunes vérifications. Les ressources minimales sont de : + +* mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). + +* CPU : même pré-requis que pour le serveur de collecte. + +Installation de centreon-esxd - Environnement centos/rhel 5 +=========================================================== + +Installation du SDK Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay + + root # cpan install Class::MethodMaker + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + root # cpan install SOAP::Lite + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +Nous avons notre environnement prêt pour l'installation du SDK VMWare. + +Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_). + +Installer le SDK Perl VMWare:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Installation de modules complémentaires +``````````````````````````````````````` + +Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : + +Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: + + root # cpan install Unix::Syslog + +Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Ensuite redémarrer votre système. + +Installation de centreon-esxd +````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* + +Installation de centreon-esxd - Environnement centos/rhel 6 +=========================================================== + +Installation du sdk Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite + + root # cpan install Test::More + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +Nous avons notre environnement prêt pour l'installation du SDK VMWare. + +Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_) + +Installer le SDK Perl VMWare:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Installation de modules complémentaires +``````````````````````````````````````` + +Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : + +Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: + + root # cpan install Unix::Syslog + +Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Ensuite redémarrer votre système. + +Installation de centreon-esxd +````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* + + diff --git a/connectors/vmware/doc-en/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc-en/_build/html/_static/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..61faf8cab23993bd3e1560bff0668bd628642330 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@Cw{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_static/basic.css b/connectors/vmware/doc-en/_build/html/_static/basic.css new file mode 100644 index 000000000..a04c8e137 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_static/basic.css @@ -0,0 +1,540 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/_static/comment-bright.png b/connectors/vmware/doc-en/_build/html/_static/comment-bright.png new file mode 100644 index 0000000000000000000000000000000000000000..551517b8c83b76f734ff791f847829a760ad1903 GIT binary patch literal 3500 zcmV;d4O8-oP)Oz@Z0f2-7z;ux~O9+4z06=<WDR*FRcSTFz- zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8 z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc- z5#WRK{dmp}uFlRjj{U%*%WZ25jX z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S z1Au6Q;m>#f??3%Vpd|o+W=WE9003S@Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG z3;bXU&9EIRU@z1_9W=mEXoiz;4lcq~xDGvV5BgyU zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi@a{RY)E3 zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv@SV$}* z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C z$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mm@+|Cqnc9PsG(F5HIG_C zt)aG3uTh7n6Et<2In9F>NlT@zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWwr)$3XQ?}=hpK0&Z&W{| zep&sA23f;Q!%st`QJ}G3cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By zLtVo_L#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2 zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd zlf9FDx_yoPJqHbk*$%56S{;6Kv~mM9!g3B(KJ}#RZ#@)!hR|78Dq|Iq-afF%KE1Brn_fm;Im z_u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGA zUct(O!LkCy1<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}Ti zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B zJh;4Nr^(LEJ3myURP{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o z4K@u`jhx2fBXC4{U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0 z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ? z-G|jbTmIbG@7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P` z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000JJOGiWi{{a60 z|De66lK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^RV2niQ93PPz|JOBU!-bqA3 zR5;6pl1pe^WfX zkSdl!omi0~*ntl;2q{jA^;J@WT8O!=A(Gck8fa>hn{#u{`Tyg)!KXI6l>4dj==iVKK6+%4zaRizy(5eryC3d2 z+5Y_D$4}k5v2=Siw{=O)SWY2HJwR3xX1*M*9G^XQ*TCNXF$Vj(kbMJXK0DaS_Sa^1 z?CEa!cFWDhcwxy%a?i@DN|G6-M#uuWU>lss@I>;$xmQ|`u3f;MQ|pYuHxxvMeq4TW;>|7Z2*AsqT=`-1O~nTm6O&pNEK?^cf9CX= zkq5|qAoE7un3V z^yy=@%6zqN^x`#qW+;e7j>th{6GV}sf*}g7{(R#T)yg-AZh0C&U;WA`AL$qz8()5^ zGFi2`g&L7!c?x+A2oOaG0c*Bg&YZt8cJ{jq_W{uTdA-<;`@iP$$=$H?gYIYc_q^*$ z#k(Key`d40R3?+GmgK8hHJcwiQ~r4By@w9*PuzR>x3#(F?YW_W5pPc(t(@-Y{psOt zz2!UE_5S)bLF)Oz@Z0f2-7z;ux~O9+4z06=<WDR*FRcSTFz- zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8 z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc- z5#WRK{dmp}uFlRjj{U%*%WZ25jX z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S z1Au6Q;m>#f??3%Vpd|o+W=WE9003S@Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG z3;bXU&9EIRU@z1_9W=mEXoiz;4lcq~xDGvV5BgyU zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi@a{RY)E3 zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv@SV$}* z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C z$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mm@+|Cqnc9PsG(F5HIG_C zt)aG3uTh7n6Et<2In9F>NlT@zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWwr)$3XQ?}=hpK0&Z&W{| zep&sA23f;Q!%st`QJ}G3cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By zLtVo_L#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2 zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd zlf9FDx_yoPJqHbk*$%56S{;6Kv~mM9!g3B(KJ}#RZ#@)!hR|78Dq|Iq-afF%KE1Brn_fm;Im z_u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGA zUct(O!LkCy1<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}Ti zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B zJh;4Nr^(LEJ3myURP{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o z4K@u`jhx2fBXC4{U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0 z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ? z-G|jbTmIbG@7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P` z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000JJOGiWi{{a60 z|De66lK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^RV2oe()A>y0J-2easEJ;K` zR5;6Jl3z%jbr{D#&+mQTbB>-f&3W<<%ayjKi&ZjBc2N<@)`~{dMXWB0(ajbV85_gJ zf(EU`iek}4Bt%55ix|sVMm1u8KvB#hnmU~_r<Ogd(A5vg_omvd-#L!=(BMVklxVqhdT zofSj`QA^|)G*lu58>#vhvA)%0Or&dIsb%b)st*LV8`ANnOipDbh%_*c7`d6# z21*z~Xd?ovgf>zq(o0?Et~9ti+pljZC~#_KvJhA>u91WRaq|uqBBKP6V0?p-NL59w zrK0w($_m#SDPQ!Z$nhd^JO|f+7k5xca94d2OLJ&sSxlB7F%NtrF@@O7WWlkHSDtor zzD?u;b&KN$*MnHx;JDy9P~G<{4}9__s&MATBV4R+MuA8TjlZ3ye&qZMCUe8ihBnHI zhMSu zSERHwrmBb$SWVr+)Yk2k^FgTMR6mP;@FY2{}BeV|SUo=mNk<-XSOHNErw>s{^rR-bu$@aN7= zj~-qXcS2!BA*(Q**BOOl{FggkyHdCJi_Fy>?_K+G+DYwIn8`29DYPg&s4$}7D`fv? zuyJ2sMfJX(I^yrf6u!(~9anf(AqAk&ke}uL0SIb-H!SaDQvd(}07*qoM6N<$g1Ha7 A2LJ#7 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_static/comment.png b/connectors/vmware/doc-en/_build/html/_static/comment.png new file mode 100644 index 0000000000000000000000000000000000000000..92feb52b8824c6b0f59b658b1196c61de9162a95 GIT binary patch literal 3445 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 Xn!ZpXD%P(H00000NkvXXu0mjf= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('

      ') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/connectors/vmware/doc-en/_build/html/_static/down-pressed.png b/connectors/vmware/doc-en/_build/html/_static/down-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..6f7ad782782e4f8e39b0c6e15c7344700cdd2527 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}Z23@f-Ava~9&<9T!#}JFtXD=!G zGdl{fK6ro2OGiOl+hKvH6i=D3%%Y^j`yIkRn!8O>@bG)IQR0{Kf+mxNd=_WScA8u_ z3;8(7x2){m9`nt+U(Nab&1G)!{`SPVpDX$w8McLTzAJ39wprG3p4XLq$06M`%}2Yk zRPPsbES*dnYm1wkGL;iioAUB*Or2kz6(-M_r_#Me-`{mj$Z%( literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_static/down.png b/connectors/vmware/doc-en/_build/html/_static/down.png new file mode 100644 index 0000000000000000000000000000000000000000..3003a88770de3977d47a2ba69893436a2860f9e7 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}xaV3tUZ$qnrLa#kt978NlpS`ru z&)HFc^}^>{UOEce+71h5nn>6&w6A!ieNbu1wh)UGh{8~et^#oZ1# z>T7oM=FZ~xXWnTo{qnXm$ZLOlqGswI_m2{XwVK)IJmBjW{J3-B3x@C=M{ShWt#fYS9M?R;8K$~YwlIqwf>VA7q=YKcwf2DS4Zj5inDKXXB1zl=(YO3ST6~rDq)&z z*o>z)=hxrfG-cDBW0G$!?6{M<$@{_4{m1o%Ub!naEtn|@^frU1tDnm{r-UW|!^@B8 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_static/file.png b/connectors/vmware/doc-en/_build/html/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..d18082e397e7e54f20721af768c4c2983258f1b4 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP$HyOL$D9)yc9|lc|nKf<9@eUiWd>3GuTC!a5vdfWYEazjncPj5ZQX%+1 zt8B*4=d)!cdDz4wr^#OMYfqGz$1LDFF>|#>*O?AGil(WEs?wLLy{Gj2J_@opDm%`dlax3yA*@*N$G&*ukFv>P8+2CBWO(qz zD0k1@kN>hhb1_6`&wrCswzINE(evt-5C1B^STi2@PmdKI;Vst0PQB6!2kdN literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_static/jquery.js b/connectors/vmware/doc-en/_build/html/_static/jquery.js new file mode 100644 index 000000000..198b3ff07 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_static/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
      a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
      "+""+"
      ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
      t
      ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
      ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

      ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
      ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
      ","
      "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
      ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/_static/minus.png b/connectors/vmware/doc-en/_build/html/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..da1c5620d10c047525a467a425abe9ff5269cfc2 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknK< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/_build/html/_static/pygments.css b/connectors/vmware/doc-en/_build/html/_static/pygments.css new file mode 100644 index 000000000..d79caa151 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_static/pygments.css @@ -0,0 +1,62 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/_static/searchtools.js b/connectors/vmware/doc-en/_build/html/_static/searchtools.js new file mode 100644 index 000000000..56676b25b --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/_static/searchtools.js @@ -0,0 +1,622 @@ +/* + * searchtools.js_t + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + + +/** + * Simple result scoring code. + */ +var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + // query found in terms + term: 5 +}; + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, + dataType: "script", cache: true, + complete: function(jqxhr, textstatus) { + if (textstatus != "success") { + document.getElementById("searchindexloader").src = url; + } + }}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + var i; + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + } + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

      ' + _('Searching') + '

      ').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

      ').appendTo(this.out); + this.output = $('
      '); + } + // Prettify the comment rating. + comment.pretty_rating = comment.rating + ' point' + + (comment.rating == 1 ? '' : 's'); + // Make a class (for displaying not yet moderated comments differently) + comment.css_class = comment.displayed ? '' : ' moderate'; + // Create a div for this comment. + var context = $.extend({}, opts, comment); + var div = $(renderTemplate(commentTemplate, context)); + + // If the user has voted on this comment, highlight the correct arrow. + if (comment.vote) { + var direction = (comment.vote == 1) ? 'u' : 'd'; + div.find('#' + direction + 'v' + comment.id).hide(); + div.find('#' + direction + 'u' + comment.id).show(); + } + + if (opts.moderator || comment.text != '[deleted]') { + div.find('a.reply').show(); + if (comment.proposal_diff) + div.find('#sp' + comment.id).show(); + if (opts.moderator && !comment.displayed) + div.find('#cm' + comment.id).show(); + if (opts.moderator || (opts.username == comment.username)) + div.find('#dc' + comment.id).show(); + } + return div; + } + + /** + * A simple template renderer. Placeholders such as <%id%> are replaced + * by context['id'] with items being escaped. Placeholders such as <#id#> + * are not escaped. + */ + function renderTemplate(template, context) { + var esc = $(document.createElement('div')); + + function handle(ph, escape) { + var cur = context; + $.each(ph.split('.'), function() { + cur = cur[this]; + }); + return escape ? esc.text(cur || "").html() : cur; + } + + return template.replace(/<([%#])([\w\.]*)\1>/g, function() { + return handle(arguments[2], arguments[1] == '%' ? true : false); + }); + } + + /** Flash an error message briefly. */ + function showError(message) { + $(document.createElement('div')).attr({'class': 'popup-error'}) + .append($(document.createElement('div')) + .attr({'class': 'error-message'}).text(message)) + .appendTo('body') + .fadeIn("slow") + .delay(2000) + .fadeOut("slow"); + } + + /** Add a link the user uses to open the comments popup. */ + $.fn.comment = function() { + return this.each(function() { + var id = $(this).attr('id').substring(1); + var count = COMMENT_METADATA[id]; + var title = count + ' comment' + (count == 1 ? '' : 's'); + var image = count > 0 ? opts.commentBrightImage : opts.commentImage; + var addcls = count == 0 ? ' nocomment' : ''; + $(this) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-open' + addcls, + id: 'ao' + id + }) + .append($(document.createElement('img')).attr({ + src: image, + alt: 'comment', + title: title + })) + .click(function(event) { + event.preventDefault(); + show($(this).attr('id').substring(2)); + }) + ) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-close hidden', + id: 'ah' + id + }) + .append($(document.createElement('img')).attr({ + src: opts.closeCommentImage, + alt: 'close', + title: 'close' + })) + .click(function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }) + ); + }); + }; + + var opts = { + processVoteURL: '/_process_vote', + addCommentURL: '/_add_comment', + getCommentsURL: '/_get_comments', + acceptCommentURL: '/_accept_comment', + deleteCommentURL: '/_delete_comment', + commentImage: '/static/_static/comment.png', + closeCommentImage: '/static/_static/comment-close.png', + loadingImage: '/static/_static/ajax-loader.gif', + commentBrightImage: '/static/_static/comment-bright.png', + upArrow: '/static/_static/up.png', + downArrow: '/static/_static/down.png', + upArrowPressed: '/static/_static/up-pressed.png', + downArrowPressed: '/static/_static/down-pressed.png', + voting: false, + moderator: false + }; + + if (typeof COMMENT_OPTIONS != "undefined") { + opts = jQuery.extend(opts, COMMENT_OPTIONS); + } + + var popupTemplate = '\ +
      \ +

      \ + Sort by:\ + best rated\ + newest\ + oldest\ +

      \ +
      Comments
      \ +
      \ + loading comments...
      \ +
        \ +
        \ +

        Add a comment\ + (markup):

        \ +
        \ + reStructured text markup: *emph*, **strong**, \ + ``code``, \ + code blocks: :: and an indented block after blank line
        \ +
        \ + \ +

        \ + \ + Propose a change ▹\ + \ + \ + Propose a change ▿\ + \ +

        \ + \ + \ + \ + \ + \ +
        \ +
        '; + + var commentTemplate = '\ +
        \ +
        \ +
        \ + \ + \ + \ + \ + \ + \ +
        \ +
        \ + \ + \ + \ + \ + \ + \ +
        \ +
        \ +
        \ +

        \ + <%username%>\ + <%pretty_rating%>\ + <%time.delta%>\ +

        \ +
        <#text#>
        \ +

        \ + \ + reply ▿\ + proposal ▹\ + proposal ▿\ + \ + \ +

        \ +
        \
        +<#proposal_diff#>\
        +        
        \ +
          \ +
          \ +
          \ +
          \ + '; + + var replyTemplate = '\ +
        • \ +
          \ +
          \ + \ + \ + \ + \ + \ + \ +
          \ +
        • '; + + $(document).ready(function() { + init(); + }); +})(jQuery); + +$(document).ready(function() { + // add comment anchors for all paragraphs that are commentable + $('.sphinx-has-comment').comment(); + + // highlight search words in search results + $("div.context").each(function() { + var params = $.getQueryParameters(); + var terms = (params.q) ? params.q[0].split(/\s+/) : []; + var result = $(this); + $.each(terms, function() { + result.highlightText(this.toLowerCase(), 'highlighted'); + }); + }); + + // directly open comment window if requested + var anchor = document.location.hash; + if (anchor.substring(0, 9) == '#comment-') { + $('#ao' + anchor.substring(9)).click(); + document.location.hash = '#s' + anchor.substring(9); + } +}); diff --git a/connectors/vmware/doc-en/_build/html/exploitation/index.html b/connectors/vmware/doc-en/_build/html/exploitation/index.html new file mode 100644 index 000000000..8982a0e59 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/exploitation/index.html @@ -0,0 +1,2376 @@ + + + + + + + + Exploitation — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + +
          +
          +
          +
          + +
          +

          Exploitation¶

          +
          +

          Présentation de Centreon-esxd¶

          +
          +

          Principes Généraux¶

          +

          Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d’un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter.

          +

          Par défaut, « centreon-esxd Â» lance au moins deux processus (nommé respectivement « handle-client Â», « handle-vsphere-xxxx Â») :

          +
          +
          « handle-client Â»:
          +
          Processus en attente des demandes des clients « centreon_esx_client.pl Â».
          +
          +

          Voici le fonctionnement :

          +
            +
          • Un client se connecte.
          • +
          • Le client demande un indicateur de supervision sur un VirtualCenter.
          • +
          • Le processus « handle-client Â» fourni cette demande au processus « handle-vsphere-xxxx Â».
          • +
          • Une réponse est fournie par « handle-vsphere-xxxx Â» à « handle-client Â».
          • +
          • Le processus « handle-client Â» fourni la réponse au client.
          • +
          +
          +
          « handle-vsphere-xxxx Â»:
          +
          Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).
          +
          +

          Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande.

          +

          Centreon-esxd nécessite impérativement l’utilisation d’un (ou plusieurs) VirtualCenter. Il n’est pas possible de récupérer les informations d’un serveur ESX directement.

          +

          Voici un exemple d’architecture éclaté :

          +../_images/archi.png +
          +
          +

          Mode de fonctionnement¶

          +

          Le programme « centreon-esxd Â» fonctionne uniquement en mode « daemon Â». (dans le sens où il ne peut fournir les indicateurs sans l’utilisation d’un client).

          +

          Lors de l’utilisation du plugin centreon_esx_client.pl, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans “/usr/share/centreon/lib/centreon-esxd” et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires.

          +
          +
          +

          Configuration du connecteur¶

          +

          Le daemon « centreon-esxd Â» possède un fichier de configuration « centreon_esxd.pm Â» de la forme suivante :

          +
          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',
          +                                   'password' => 'XXXXXX'}
          +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";
          +
          +

          La variable «%vsphere_server Â» permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d’avoir au moins l’entrée ‘default’.

          +

          La variable « $port Â» permet de configurer le port d’écoute du connecteur « centreon-esxd Â».

          +

          Il est aussi possible de modifier la variable « $log_mode Â» si vous souhaitez utiliser « syslog Â» au lieu d’un fichier à plat.

          +

          Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION Â», « $TIMEOUT_KILL Â», « $ TIMEOUT_VSPHERE Â» et « $TIMEOUT Â», car ils sont configurés pour une utilisation optimale.

          +
          +
          +
          +

          Optimisation de la configuration dans Centreon¶

          +

          Afin d’exploiter pleinement « centreon-esxd Â», il est recommandé d’effectuer une série d’action préalablement.

          +

          Ce connecteur permet la définition de trois modèles d’hôtes :

          +
            +
          • le modèle hôte « VMWare-VM Â» : modèle d’une machine virtuelle.
          • +
          • le modèle hôte « VMWare-ESX Â» : modèle d’un serveur ESX.
          • +
          • le modèle hôte « VMWare-VC Â» : modèle d’un virtualCenter (Ce modèle contient notamment des services pour les « datastores Â»)
          • +
          +

          Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration.

          +
          +++++ + + + + + + + + + + + + + + + + + + + + +
          Macro NameMacro ValueRessource ou la macro doit être défini (recommandé)
          HOSTESXDHOSTIp ou nom d’hôte du serveur exécutant le daemon « centreon-esxd Â»Modèle d’hôte VMWare-* de plus bas niveau
          HOSTESXDPORTPort du daemonModèle d’hôte VMWare-* de plus bas niveau
          HOSTVCNAMENom identifiant le VirtualCenterModèle d’hôte VMWare-* de plus bas niveau
          +

          Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm Â» qui se situe normalement dans “/etc/centreon/centreon_esxd.pm” . Ce système évite la visualisation d’un mot de passe dans l’interface « centreon Â».

          +
          +

          Création d’un modèle d’hôte VMWare générique¶

          +

          Aller dans le menu configuration/host/template/, et créer un modèle d’hôte « VMWare Â». Ce modèle d’hôte sera le modèle parent pour les modèles « VMWare-VM Â», « VMWare-ESX Â» et « VMWare-VC Â».

          +

          Configurer l’ensemble des champs comme indiqué dans la documentation Centreon.

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + + + + +
          Macro NameMacro Value
          ESXDHOSTExemple: 10.30.10.30
          ESXDPORT5700 (port par défaut)
          VCNAMEdefault
          +
          +
          +

          Troubleshooting¶

          +

          Il est possible de retrouver des erreurs de ce type dans les « log Â» de « centreon-esxd Â» :

          +
          ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac...
          +
          +
          +

          Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur.

          +

          Il est nécessaire de remonter un problème dans le cas d’un trop grand nombres de déconnexion du daemon au VirtualCenter.

          +
          + +
          +

          Liste des contrôles¶

          +
          +

          Contrôles ESX¶

          +
          +

          CPU¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_cpuhost
          DescriptionContrôle le taux d’utilisation CPU d’un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs.
          Fonctionnement
            +
          • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéescpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100
          Interval/Retry(min)5/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlercpuhost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
          --light-perfdata(optionnel) Permet d’afficher uniquement la perfdata du CPU total 
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING80
          CRITICAL90
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          MEMOIRE¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_memhost
          Description
          +
          Contrôle le taux d’utilisation mémoire d’un serveur ESX. 3 métriques sont renvoyés :
          +
            +
          • le taux d’utilisation mémoire (en octets),
          • +
          • la taille totale de la mémoire (en octets),
          • +
          • la mémoire suralloué par la totalité des VMs (‘overhead’ en octets)
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéesused=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o
          Interval/Retry(min)20/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlermemhost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING80
          CRITICAL90
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          RESEAU¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_nethost
          Description
          +
          Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés :
          +
            +
          • le taux d’utilisation en entrée et sortie (en b/s).
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la(les) métrique(s) « traffic_* Â» est(sont) au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéestraffic_in=598016b/s traffic_out=172032b/s
          Interval/Retry(min)5/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlernethost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          --nicNom de l’interface réseau physiquevmnic0
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + + + + +
          Macro NameMacro Value
          NICNAME 
          WARNING80
          CRITICAL90
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$"
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          SWAP¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_swaphost
          Description
          +
          Contrôle le taux d’utilisation mémoire d’un serveur ESX. 2 métriques sont renvoyés :
          +
            +
          • le taux de lecture et d’écriture du swap globale de l’ensemble des machines virtuelles (en Mb/s).
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la(les) métrique(s) « swap_* Â» est(sont) au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéesswap_in=0b/s swap_out=0b/s
          Interval/Retry(min)20/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerswaphost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          -w ou --warning(optionnel – Défaut : 0.8) Seuil warning en MB/s0.5
          -c ou --critical(optionnel – Défaut : 1) Seuil critique en MB/s1.5
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING0.8
          CRITICAL1
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          DATASTORES¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_datastoreshost
          Description
          +
          Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés par le datastore :
          +
            +
          • la latence totale en lecture et écriture (en ms).
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyées‘trl_LUN1’=0.00ms ‘twl_LUN1’=0.00ms ‘trl_LUN2’=0.00ms ‘twl_LUN2’=1.00ms
          Interval/Retry(min)5/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerdatastoreshost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          --filter-datastores(optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules)LUN1,LUN2
          -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms75
          -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms90
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING30
          CRITICAL50
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          COUNTVM¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_countvmhost
          Description
          +
          Contrôle le taux d’utilisation mémoire d’un serveur ESX. 1 métrique est remontée :
          +
            +
          • le nombre de machines virtuelles allumées.
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la métrique « count Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « count Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « count Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéescount=45
          Interval/Retry(min)20/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlercountvmhost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          -w ou --warning(optionnel – Défaut : aucunes valeurs) Seuil warning en ms10
          -c ou --critical(optionnel – Défaut : aucunes valeurs) Seuil critique en ms15
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING10
          CRITICAL15
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          HEALTH¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_healthhost
          DescriptionContrôle l’état des sondes matériels et processeurs d’un serveur ESX.
          Fonctionnement
          +
          Remonte un état selon l’état des sondes:
          +
            +
          • “Yellow” correspond à WARNING.
          • +
          • “Red” correspond à CRITICAL.
          • +
          +
          +
          +
          Métriques renvoyées 
          Interval/Retry(min)30/1
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerhealthhost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
            
            
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          MAINTENANCE¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_maintenancehost
          DescriptionContrôle le mode de maintenance d’un serveur ESX.
          Fonctionnement
            +
          • Remonte l’état « CRITICAL » si le serveur ESX est en mode de maintenance.
          • +
          +
          Métriques renvoyées 
          Interval/Retry(min)30/1
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlermaintenancehost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
            
            
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          STATUT¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_statushost
          DescriptionContrôle l’état global d’un serveur ESX.
          Fonctionnement
            +
          • Remonte l’état « CRITICAL » si le statut du serveur ESX est en « red » .
          • +
          • Remonte l’état « WARNING » si le statut du serveur ESX est en « yellow » .
          • +
          • Remonte l’état « UNKNOWN » si le statut du serveur ESX est en « gray » .
          • +
          +
          Métriques renvoyées 
          Interval/Retry(min)30/1
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerstatushost
          -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
            
            
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +
          +

          Contrôles d’une machine virtuelle¶

          +
          +

          CPU¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_cpuvm
          DescriptionContrôle le taux d’utilisation CPU d’une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs.
          Fonctionnement
            +
          • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéescpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz
          Interval/Retry(min)5/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlercpuvm
          --vmNom de la machine virtuelle cibléemyvmname
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING80
          CRITICAL90
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          MEMOIRE¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_memvm
          Description
          +
          Contrôle le taux d’utilisation mémoire d’une machine virtuelle. 6 métriques sont renvoyés :
          +
            +
          • « used Â» : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets)
          • +
          • « size Â» : la taille totale de la mémoire allouée pour la machine virtuelle (en octets)
          • +
          • « overhead Â» : la mémoire sur-alloué (en octets)
          • +
          • « ballooning Â», « shared Â» et « active Â».
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéesusage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o
          Interval/Retry(min)20/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlermemvm
          --vmNom de la machine virtuelle cibléemyvmname
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING80
          CRITICAL90
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          DATASTORES¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_datastoresvm
          Description
          +
          Contrôle le taux d’utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore :
          +
            +
          • « riops Â» : le nombre moyen d’I/O de lectures par seconde
          • +
          • « wiops Â» : le nombre moyen d’I/O d’écritures par seconde
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si une métrique est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyées‘riops_LUN1’=0.00iops ‘wiops_LUN1’=0.27iops ‘riops_LUN2’=20.00iops ‘wiops_LUN2’=100.2iops
          Interval/Retry(min)5/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerdatastoresvm
          --vmNom de la machine virtuelle cibléemyvmname
          -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms100
          -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms150
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          WARNING100
          CRITICAL150
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          VMTOOLS¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_toolsvm
          DescriptionContrôle l’état des VMTools rattachées à une machine virtuelle.
          Fonctionnement
            +
          • Remonte l’état « WARNING » si les VMTools sont ‘toolsold’.
          • +
          • Remonte l’état « CRITICAL » si les VMTools sont ‘toolsnotrunning’ ou ‘toolsnotinstalled’.
          • +
          +
          Métriques renvoyées 
          Interval/Retry(min)20/1
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlertoolsvm
          --vmNom de la machine virtuelle cibléemyvmname
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
            
            
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          SNAPSHOTS¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_snapshotvm
          DescriptionContrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle.
          Fonctionnement
          +
          L’état dépend des paramètres du plugin :
          +
            +
          • Si « –warn Â» spécifié seul : remonte un état WARNING si un snapshost est présent.
          • +
          • Si « –crit Â» spécifié seul : remonte un état CRITICAL si un snapshost est présent.
          • +
          • Si « –warn Â» et « –older XXX Â» : remonte un état WARNING si un snapshost est présent et la date de création du +snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
          • +
          • Si « –crit Â» et « –older XXX Â» : remonte un état CRITICAL si un snapshost est présent et la date de création du +snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
          • +
          +
          +
          +
          Métriques renvoyées 
          Interval/Retry(min)20/1
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlersnapshotvm
          --vmNom de la machine virtuelle cibléemyvmname
          --warn(optionnel) Permet de spécifier un état WARNING 
          --crit(optionnel) Permet de spécifier un état CRITICAL 
          --older(optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant86400 (snapshot vieux de + 1jour)
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + +
          Macro NameMacro Value
          THRESHOLD
            +
          • -warn
          • +
          +
            
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +
          +

          Contrôle d’un datastore¶

          +
          +

          USAGE¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_datastoreusage
          Description
          +
          Contrôle le taux d’utilisation d’un datastore. 2 métriques sont renvoyés :
          +
            +
          • « used Â» : l’espace occupé par le datastore (en octets)
          • +
          • « size Â» : la taille totale allouée pour le datastore (en octets)
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéesused=506574405632o;;;0;643976658944 size=643976658944o
          Interval/Retry(min)20/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerdatastore-usage
          -e ou --esx-hostNom du datastore ciblédsname
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + + + + +
          Macro NameMacro Value
          DSNAME 
          WARNING80
          CRITICAL90
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +

          DATASTORE I/O¶

          +
          +
          Fiche d’identité¶
          + ++++ + + + + + + + + + + + + + + + + + +
          Nom du plugincheck_merethis_vmware_datastorio
          Description
          +
          Contrôle le taux d’utilisation (I/O) d’un datastore. 2 métriques sont renvoyés :
          +
            +
          • « read_rate Â» : le taux d’utilisation moyen en lecture par seconde (en b/s)
          • +
          • « write_rate Â» : la taille d’utilisation moyen en écriture par seconde (en b/s)
          • +
          +
          +
          +
          Fonctionnement
            +
          • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
          • +
          • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
          • +
          • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
          • +
          +
          Métriques renvoyéesread_rate=1589248b/s write_rate=14344192b/s
          Interval/Retry(min)5/5
          +
          +
          +
          Attribut du contrôle¶
          + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
          AttributDescriptionExemple
          -uIndicateur à contrôlerdatastore-io
          -e ou --esx-hostNom du datastore ciblédsname
          -w ou --warning(optionnel – Défaut : 80) Seuil warning en kBps100
          -c ou --critical(optionnel – Défaut : 90) Seuil critique en kBps200
          +

          Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

          + ++++ + + + + + + + + + + + + + +
          OptionComportement
          -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
          -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          +
          +
          +
          Création d’un service et/ou modèle de service¶
          +

          Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

          +

          Définir les macros suivante :

          + ++++ + + + + + + + + + + + + + + + + +
          Macro NameMacro Value
          DSNAME 
          WARNING100
          CRITICAL150
          +
          +
          +
          Création d’une check command¶
          +

          Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

          +
          $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
          +
          +

          L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

          +
          +
          +
          +
          + + + + + + +
          +
          +

          Table Of Contents

          + + +

          Previous topic

          +

          Installation

          +

          This Page

          + + + +
          +
          +
          + + + + + \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/genindex.html b/connectors/vmware/doc-en/_build/html/genindex.html new file mode 100644 index 000000000..461f46511 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/genindex.html @@ -0,0 +1,92 @@ + + + + + + + + + Index — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + +
          +
          +
          +
          + + +

          Index

          + +
          + +
          + + +
          +
          +
          +
          +
          + + + + + +
          +
          +
          +
          + + + + \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/index.html b/connectors/vmware/doc-en/_build/html/index.html new file mode 100644 index 000000000..7bce10796 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/index.html @@ -0,0 +1,133 @@ + + + + + + + + Welcome to Centreon ESXD’s documentation! — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + +
          + +
          +
          +

          Table Of Contents

          + + +

          Next topic

          +

          Installation

          +

          This Page

          + + + +
          +
          +
          +
          + + + + \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/installation/index.html b/connectors/vmware/doc-en/_build/html/installation/index.html new file mode 100644 index 000000000..9b05d179c --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/installation/index.html @@ -0,0 +1,314 @@ + + + + + + + + Installation — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + + +
          +
          +
          +
          + +
          +

          Installation¶

          +
          +

          Pré-Requis¶

          +
          +

          Préconisations logicielles¶

          +

          Le connecteur “centreon-esxd” est testé et validé sur des environnements Linux. +L’installation sur d’autres environnements n’est pas exclu mais non présenté dans ce document (Solaris, Windows, ...).

          + ++++ + + + + + + + + + + + + + + + + +
          LogicielsVersion minimum
          VMWare SDK Perl5.0
          Perl5.8
          centreon-esxd1.3
          +
          +
          +

          Préconisations matérielles¶

          +

          Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n’effectue aucunes vérifications. Les ressources minimales sont de :

          +
            +
          • mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle).
          • +
          • CPU : même pré-requis que pour le serveur de collecte.
          • +
          +
          +
          +
          +

          Installation de centreon-esxd - Environnement centos/rhel 5¶

          +
          +

          Installation du SDK Perl VMWare¶

          +

          Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l’installer. Pour cela nous allons commencer par installer CPAN qui est le nom d’un module Perl qui rend aisés le téléchargement, l’installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN.

          +

          Installer les pré-requis CPAN:

          +
          root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel
          +root # yum install perl-XML-LibXML perl-Crypt-SSLeay
          +
          +root # cpan install Class::MethodMaker
          +root # cpan install LWP
          +root # cpan install Net::SSLeay
          +root # cpan install LWP::Protocol::https
          +root # cpan install SOAP::Lite
          +
          +root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
          +root # tar zxvf UUID-0.04.tar.gz
          +root # cd UUID-0.04
          +root # perl Makefile.PL
          +root # make && make install
          +
          +
          +

          Nous avons notre environnement prêt pour l’installation du SDK VMWare.

          +

          Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (SDK VMWare).

          +

          Installer le SDK Perl VMWare:

          +
          root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
          +root # cd vmware-vsphere-cli-distrib
          +root # perl Makefile.pl
          +root # make && make install
          +
          +
          +
          +
          +

          Installation de modules complémentaires¶

          +

          Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd :

          +

          Pour envoyer les logs au daemon « syslog Â», il est nécessaire d’installer le module « Unix::Syslog »:

          +
          root # cpan install Unix::Syslog
          +
          +
          +

          Pour vérifier la date des snapshots d’une machine virtuelle, il est nécessaire d’installer le module « DateTime::Format::ISO8601 Â» ( ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl Â». Cette mise à jour est très risqué ):

          +
          root # cpan install DateTime
          +root # cpan install DateTime::Format::ISO8601
          +root # o conf make /usr/bin/make
          +root # o conf commit
          +
          +
          +

          Ensuite redémarrer votre système.

          +
          +
          +

          Installation de centreon-esxd¶

          +

          Télécharger l’archive de « centreon-esxd Â».

          +

          Installer les fichiers:

          +
          root # tar zxvf centreon-esxd-1.X.tar.gz
          +root # cd centreon-esxd-1.X
          +root # cp centreon_esxd /usr/bin/
          +
          +root # mkdir -p /etc/centreon
          +root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
          +root # cp centreon_esxd-init /etc/init.d/centreon_esxd
          +
          +root # mkdir -p /usr/share/centreon/lib/centreon-esxd
          +root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
          +
          +
          +

          Activer le daemon « centreon-esxd Â» au démarrage:

          +
          root # chkconfig --level 2345 centreon_esxd on
          +
          +
          +

          Le plugin « nagios Â» correspond au fichier « centreon_esx_client.pl Â».

          +
          +
          +
          +

          Installation de centreon-esxd - Environnement centos/rhel 6¶

          +
          +

          Installation du sdk Perl VMWare¶

          +

          Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement.

          +

          Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l’installer. Pour cela nous allons commencer par installer CPAN qui est le nom d’un module Perl qui rend aisés le téléchargement, l’installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN.

          +

          Installer les pré-requis CPAN:

          +
          root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel
          +root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite
          +
          +root # cpan install Test::More
          +root # cpan install LWP
          +root # cpan install Net::SSLeay
          +root # cpan install LWP::Protocol::https
          +
          +root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
          +root # tar zxvf UUID-0.04.tar.gz
          +root # cd UUID-0.04
          +root # perl Makefile.PL
          +root # make && make install
          +
          +
          +

          Nous avons notre environnement prêt pour l’installation du SDK VMWare.

          +

          Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (SDK VMWare)

          +

          Installer le SDK Perl VMWare:

          +
          root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
          +root # cd vmware-vsphere-cli-distrib
          +root # perl Makefile.pl
          +root # make && make install
          +
          +
          +
          +
          +

          Installation de modules complémentaires¶

          +

          Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd :

          +

          Pour envoyer les logs au daemon « syslog Â», il est nécessaire d’installer le module « Unix::Syslog »:

          +
          root # cpan install Unix::Syslog
          +
          +
          +

          Pour vérifier la date des snapshots d’une machine virtuelle, il est nécessaire d’installer le module « DateTime::Format::ISO8601 Â» ( ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl Â». Cette mise à jour est très risqué ):

          +
          root # cpan install DateTime
          +root # cpan install DateTime::Format::ISO8601
          +root # o conf make /usr/bin/make
          +root # o conf commit
          +
          +
          +

          Ensuite redémarrer votre système.

          +
          +
          +

          Installation de centreon-esxd¶

          +

          Télécharger l’archive de « centreon-esxd Â».

          +

          Installer les fichiers:

          +
          root # tar zxvf centreon-esxd-1.X.tar.gz
          +root # cd centreon-esxd-1.X
          +root # cp centreon_esxd /usr/bin/
          +
          +root # mkdir -p /etc/centreon
          +root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
          +root # cp centreon_esxd-init /etc/init.d/centreon_esxd
          +
          +root # mkdir -p /usr/share/centreon/lib/centreon-esxd
          +root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
          +
          +
          +

          Activer le daemon « centreon-esxd Â» au démarrage:

          +
          root # chkconfig --level 2345 centreon_esxd on
          +
          +
          +

          Le plugin « nagios Â» correspond au fichier « centreon_esx_client.pl Â».

          +
          +
          +
          + + +
          +
          +
          + +
          +
          + + + + \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/objects.inv b/connectors/vmware/doc-en/_build/html/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..6b9e7d70341d5f6891429e463885b3a060ed17b1 GIT binary patch literal 209 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~KjbN*1L8MO}j< zT!0c`5JgrBhI$4-Zb(L|LQ!gNVrE`SYLP;InnFoNX0bwAW=^UCkWS9eEhtJYE>2BR zC@s#+OIN7M$xPDYs + + + + + + + Search — Centreon ESXD 1.0.0 documentation + + + + + + + + + + + + + + + + + + + +
          +
          +
          +
          + +

          Search

          +
          + +

          + Please activate JavaScript to enable the search + functionality. +

          +
          +

          + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

          +
          + + + +
          + +
          + +
          + +
          +
          +
          +
          +
          +
          +
          +
          +
          + + + + \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/searchindex.js b/connectors/vmware/doc-en/_build/html/searchindex.js new file mode 100644 index 000000000..6a665ac86 --- /dev/null +++ b/connectors/vmware/doc-en/_build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{"2iop":2,code:[],check_merethis_vmware_datastorio:2,trl_lun2:2,librairi:2,global:[1,2],troi:2,yellow:2,"\u00e9clat\u00e9":2,fourni:2,row:[],indicateur:2,"27iop":2,init:1,"surallou\u00e9":2,aux:2,valeur:2,"d\u00e9j\u00e0":2,sond:2,"valid\u00e9":1,"22743040o":2,sont:[1,2],garder:2,check_merethis_vmware_nethost:2,level:1,"d\u00e9marrag":1,servic:[],x86_64:1,visualis:2,"362747904o":2,"derni\u00e8r":1,direct:2,syslog:[1,2],second:2,pass:2,port:2,vmware:[],supervis:2,"_hostvcnam":2,section:[],quelqu:2,statushost:2,riops_lun1:2,communiqu:2,version:1,sur:[1,2],peuvent:[1,2],net:1,cela:[1,2],"charg\u00e9":2,"contr\u00f4ler":2,voici:2,snapshost:2,bodi:[],solari:1,"fonctionnalit\u00e9":1,modifi:2,valu:2,"m\u00eame":1,"tr\u00e8":1,search:[0,1],"v\u00e9rific":1,"r\u00e9cup\u00e8r":2,beaucoup:1,host:2,datetim:1,action:2,que:[1,2],environn:[],"risqu\u00e9":1,modul:[],souhaitez:[1,2],unix:[1,2],instal:[],total:2,"1773761536o":2,commun:2,lwp:1,pourcentag:2,perl:[],latenc:2,overhead:2,rhel:[],vcenter:2,type:2,more:1,ensuit:[1,2],riop:2,check_merethis_vmware_cpuhost:2,log_daemon:2,filtrer:2,check_merethis_vmware_datastoresvm:2,iso8601:1,warn:2,twl_lun2:2,twl_lun1:2,moin:2,cach:2,"rattach\u00e9":2,augment:1,car:2,uniqu:2,pour:[1,2],minimum:1,taux:2,nagio:1,root:1,"506574405632o":2,tar:1,requi:[],share:[1,2],check_merethis_vmware_swaphost:2,templat:2,critic:2,unzip:1,check_merethis_vmware_healthhost:2,"r\u00e9pons":2,traffic_out:2,suivant:2,gcc:1,refresh_keeper_sess:2,"totalit\u00e9":2,rapport:2,write:[],toolsnotinstal:2,optimal:2,xxxx:2,swap_in:2,mac:2,attent:2,mai:[1,2],datastoresvm:2,datastor:[],"remont\u00e9":2,souci:2,permet:2,light:2,timeout_kil:2,correspond:[1,2],allon:1,issu:2,inform:2,ensembl:2,make:1,"m\u00e9moir":[1,2],"d\u00e9faut":[1,2],offici:[],peut:[1,2],"00mhz":2,afin:2,"h\u00e9bergeant":2,kbp:2,jnh:1,"r\u00e9colter":2,"_servicethreshold":2,uuid:1,window:1,"\u00e9critur":2,memhost:2,nom:[1,2],non:1,"syst\u00e8m":[1,2],handl:2,dan:1,taill:2,devel:1,"\u00e9galement":2,effectu:[1,2],autr:1,optionnel:2,nou:1,"1jour":2,"bas\u00e9":2,critiqu:2,name:2,aucun:[1,2],temps_cour:2,"install\u00e9":1,check_merethis_vmware_datastoreusag:2,timeout:2,champ:2,cett:[1,2],espac:2,"cr\u00e9er":2,connect:2,"r\u00e9seau":2,distrib:1,our:2,"probl\u00e8m":2,variabl:2,respectiv:2,mettr:1,"nomm\u00e9":2,content:0,"\u00e9cout":2,traffic_in:2,centreon_esxd:[1,2],red:2,serveur:[1,2],"contr\u00f4l":1,check_merethis_vmware_maintenancehost:2,e2fsprog:1,qui:[1,2],org:1,selon:2,contient:2,libuuid:1,openssl:1,filter:2,liaison:2,yum:1,unknown:2,processeur:2,"r\u00e9sultat":2,"pr\u00e9sent\u00e9":1,check_merethis_vmware_countvmhost:2,mise:1,"pr\u00e9":[],votr:1,affich:2,donc:1,"indiqu\u00e9":2,crit:2,virtualcent:2,tou:2,ont:2,size:2,fonctionn:[],"_hostesxdport":2,mkdir:1,trl_lun1:2,nethost:2,"final":2,shell:[],option:2,"poss\u00e8d":2,cpu2:2,cpu3:2,specifi:2,cpu1:2,"d\u00e9pend":[1,2],date:[1,2],centreon_esx_cli:[1,2],ssl3_get_record:2,"00iop":2,older:2,wiops_lun2:2,wiops_lun1:2,timeout_vspher:2,ressourc:[1,2],sera:2,"red\u00e9marr":1,cpu_total_mhz:2,"acc\u00e8":2,aussi:2,myvmnam:2,"56196403200o":2,wiop:2,jour:1,lib:[1,2],min:2,hostvcnam:2,"d\u00e9connexion":2,libpath:2,fonction:1,deux:2,soap:[1,2],simplifi:2,macro:2,"sp\u00e9cifier":2,index:0,usernam:2,"configur\u00e9":2,plat:2,doit:2,dessu:2,maintenancehost:2,cpu0:2,"v\u00e9rifier":1,toolsnotrun:2,"class":1,url:2,request:2,snapshot:1,"_servicedsnam":2,"68705865728o":2,"\u00e9tat":2,vcname:2,"n\u00e9cessair":[1,2],"cr\u00e9\u00e9":2,text:[],session:2,threshold:2,identifi:2,trop:2,retrouv:2,xml:1,fichier:[1,2],menu:2,activ:[1,2],"cr\u00e9ant":2,"70148096o":2,"diff\u00e9rent":2,"s\u00e9par\u00e9":2,yml:[],count:2,cpuvm:2,ssl:2,mainten:1,"pr\u00eat":1,"t\u00e9l\u00e9chargement":1,vsphere_serv:2,"172032b":2,"2147483648o":2,snapshotvm:2,grai:2,bad:2,write_r:2,"\u00e9vite":2,"caract\u00e8r":2,swap_out:2,riops_lun2:2,"643976658944o":2,"_servicecrit":2,"recommand\u00e9":2,fail:2,sen:2,xxxxx:2,sorti:2,nombr:[1,2],vont:2,"_servicewarn":2,attribut:[],parent:2,check_merethis_vmware_memhost:2,officiel:1,comm:2,avon:1,cli:1,plugin:[1,2],"sp\u00e9cifi\u00e9":2,etc:[1,2],erreur:2,rend:1,login:2,"allou\u00e9":2,"d\u00e9conseill\u00e9":2,makefil:1,"d\u00e9finit":2,perfdata:2,"d\u00e9finir":2,linux:1,connexion:2,aller:2,json:[],"pr\u00e9sent":2,difficil:1,datastoreshost:2,cpu_tot:2,xxx:2,demand:[1,2],viperltoolkit:[],toolsvm:2,"entr\u00e9":2,"ais\u00e9":1,"_hostesxdhost":2,error:2,"1408f119":2,stdout:2,envoy:1,expat:1,"4561920o":2,"allum\u00e9":2,"00m":2,vou:[1,2],libxml:1,archiv:1,cento:[],conf:1,chkconfig:1,situ:2,par:[1,2],develop:[],log_crit:2,author:1,perform:2,balloon:2,memvm:2,"pr\u00e9senc":2,"ex\u00e9cut":2,"imp\u00e9rativ":2,traiter:2,grand:2,lite:1,http:[1,2],ouvr:2,nic:2,nicnam:2,vieux:2,moyen:2,"h\u00f4te":[],com:[],notr:1,"r\u00e9cup\u00e9rer":2,traffic_:2,client:2,command:[],titl:[],san:[1,2],programm:2,"g\u00e9n\u00e8re":2,protocol:[1,2],physiqu:2,tcp:2,processu:2,ayant:2,connecteur:1,bit:1,"renvoy\u00e9":2,site:1,virgul:2,toolsold:2,exempl:2,"cibl\u00e9":2,bloc:[],log_facil:2,enfin:2,check_merethis_vmware_snapshotvm:2,adress:2,esxdhost:2,bin:1,xxxxxx:2,format:1,read:2,mot:2,cpan:[],remont:2,check_merethis_vmware_datastoreshost:2,healthhost:2,password:2,daemon:[1,2],header:[],fournir:2,"d\u00e9fini":2,dsname:2,noth:2,collect:1,"pr\u00e9alabl":2,page:0,"r\u00f4le":2,www:[],besoin:2,swap_:2,interv:2,seuil:2,"14344192b":2,log_mod:2,hostesxdhost:2,bloqu:2,"n\u00e9cessit":2,ouvert:2,tmp:2,est:[1,2],swaphost:2,octet:2,esx:[],retri:2,avoir:2,minimal:1,machin:1,plu:2,sensibl:1,ancien:2,usag:[],virtuel:1,"test\u00e9":1,wget:1,"\u00eatre":[1,2],column:[],commit:1,"donn\u00e9":2,zxvf:1,routin:2,read_rat:2,vsphere:[1,2],son:[1,2],lier:2,"archiv\u00e9":1,sou:2,retourn:2,lieu:2,mymeta:[],testvc:2,log:[1,2],plusieur:2,support:[],logiciel:[],lor:2,esx1:2,interfac:2,comport:2,"1589248b":2,methodmak:1,usr:[1,2],lun2:2,lun1:2,pleinement:2,form:2,link:[],cpuhost:2,sdk:[],info:2,vive:1,temp:2,possibl:2,"default":2,avec:2,record:2,"cha\u00een":2,notam:2,vmnic0:2,"s\u00e9rie":2,user1:2,certain:1,utilis:[1,2],decrypt:2,lectur:2,"m\u00e9triqu":2,file:2,dessou:2,"mod\u00e8l":[],hostesxdport:2,commenc:1,"occup\u00e9":2,courant:2,check_merethis_vmware_statushost:2,crypt:1,seul:2,"_servicenicnam":2,normal:2,viell:2,test:[1,2],snaphost:2,architectur:[1,2],countvmhost:2,check_merethis_vmware_toolsvm:2,cpu0_mhz:2,hostaddress:2,"param\u00e8tr":2,check_merethis_vmware_cpuvm:2,lanc:2,niveau:2,exclu:1,ssleai:1,descript:2,check_merethis_vmware_memvm:2,"598016b":2,esxdport:2,"t\u00e9l\u00e9charger":1,cpu:1},objtypes:{},objnames:{},filenames:["index","installation/index","exploitation/index"],titles:["Welcome to Centreon ESXD’s documentation!","Installation","Exploitation"],objects:{},titleterms:{configur:2,modul:1,requi:1,"pr\u00e9":1,"contr\u00f4l":2,indic:0,exploit:2,cento:1,tabl:0,instal:1,"cr\u00e9ation":2,connecteur:2,check:2,vmware:[1,2],centreon:[0,1,2],reseau:2,welcom:0,"mod\u00e8l":2,titl:[],section:[],"mat\u00e9riel":1,logiciel:1,perl:1,health:2,rhel:1,optimisationd:[],document:0,memoir:2,attribut:2,machin:2,swap:2,statut:2,dan:2,usag:2,"identit\u00e9":2,"pr\u00e9conis":1,"h\u00f4te":2,"g\u00e9n\u00e9riqu":2,mainten:2,cpan:[],datastor:2,fonctionn:2,countvm:2,sdk:1,vmtool:2,esxd:[0,1,2],"compl\u00e9mentair":1,optimis:2,command:2,troubleshoot:2,"g\u00e9n\u00e9raux":2,list:2,virtuel:2,"pr\u00e9sentat":2,princip:2,snapshot:2,mode:2,esx:2,fich:2,servic:2,cpu:2,environn:1}}) \ No newline at end of file diff --git a/connectors/vmware/doc-en/conf.py b/connectors/vmware/doc-en/conf.py new file mode 100644 index 000000000..e9144e890 --- /dev/null +++ b/connectors/vmware/doc-en/conf.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# +# Centreon ESXD documentation build configuration file, created by +# sphinx-quickstart on Mon Apr 22 11:17:38 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Centreon ESXD' +copyright = u'2013, Merethis' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '1.0' +# The full version, including alpha/beta/rc tags. +release = '1.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'CentreonESXDdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'CentreonESXD.tex', u'Centreon ESXD Documentation', + u'Merethis', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'centreonesxd', u'Centreon ESXD Documentation', + [u'Merethis'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'CentreonESXD', u'Centreon ESXD Documentation', + u'Merethis', 'CentreonESXD', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/connectors/vmware/doc-en/exploitation/index.rst b/connectors/vmware/doc-en/exploitation/index.rst new file mode 100644 index 000000000..ea9bede9a --- /dev/null +++ b/connectors/vmware/doc-en/exploitation/index.rst @@ -0,0 +1,1384 @@ +============ +Exploitation +============ + +Centreon-esxd Presentation +--------------------------- + +Principes Généraux +`````````````````` + +Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. + +Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : + +*« handle-client »*: + *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + +Voici le fonctionnement : + +- Un client se connecte. +- Le client demande un indicateur de supervision sur un VirtualCenter. +- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». +- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». +- Le processus « handle-client » fourni la réponse au client. + +*« handle-vsphere-xxxx »*: + *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* + +Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. + +Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. + +Voici un exemple d'architecture éclaté : + +.. image:: ../images/archi.png + +Mode de fonctionnement +`````````````````````` +Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). + +Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. + +Configuration du connecteur +``````````````````````````` +Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: + + 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', + 'password' => 'XXXXXX'} + 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"; + +La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. + +La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». + +Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. + +Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. + + +Optimisation de la configuration dans Centreon +---------------------------------------------- + +Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. + +Ce connecteur permet la définition de trois modèles d'hôtes : + +- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. +- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. +- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») + +Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. + ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | +| | | | ++====================+===================================================================+================================================================+ +| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ +| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | ++--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ + +Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». + + +Création d'un modèle d'hôte VMWare générique +```````````````````````````````````````````` + +Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». + +Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. + +Définir les macros suivante : + ++---------------------+-------------------------------------------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+===================================================================+ +| ESXDHOST | Exemple: 10.30.10.30 | ++---------------------+-------------------------------------------------------------------+ +| ESXDPORT | 5700 (port par défaut) | ++---------------------+-------------------------------------------------------------------+ +| VCNAME | default | ++---------------------+-------------------------------------------------------------------+ + +Troubleshooting +``````````````` + +Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: + + ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... + +Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. + +Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. + + +Liste des contrôles +------------------- + +Contrôles ESX +````````````` +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++===========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuhost | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | ++---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | +| | - le taux d'utilisation mémoire (en octets), | +| | - la taille totale de la mémoire (en octets), | +| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memhost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +RESEAU +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_nethost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux d'utilisation en entrée et sortie (en b/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | nethost | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| NICNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +SWAP +'''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_swaphost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | +| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | swaphost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 0.8 | ++---------------------+--------------------------------+ +| CRITICAL | 1 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreshost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | +| | - la latence totale en lecture et écriture (en ms). | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++============================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoreshost | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | ++----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 30 | ++---------------------+--------------------------------+ +| CRITICAL | 50 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +COUNTVM +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_countvmhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | +| | - le nombre de machines virtuelles allumées. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | count=45 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | countvmhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 10 | ++---------------------+--------------------------------+ +| CRITICAL | 15 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +HEALTH +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_healthhost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | Remonte un état selon l'état des sondes: | +| | - "Yellow" correspond à WARNING. | +| | - "Red" correspond à CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | healthhost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MAINTENANCE +''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_maintenancehost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | maintenancehost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +STATUT +'''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_statushost | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état global d'un serveur ESX. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | +| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | +| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 30/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | statushost | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôles d'une machine virtuelle +````````````````````````````````` + +CPU +''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_cpuvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | cpuvm | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +MEMOIRE +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_memvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | +| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | +| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | +| | - « overhead » : la mémoire sur-alloué (en octets) | +| | - « ballooning », « shared » et « active ». | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | memvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORES +'''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoresvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | +| | - « riops » : le nombre moyen d'I/O de lectures par seconde | +| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++==========================+====================================================================================+================================================================+ +| -u | Indicateur à contrôler | datastoresvm | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | ++--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + +VMTOOLS +''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_toolsvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | +| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | toolsvm | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| | | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +SNAPSHOTS +''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_snapshotvm | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | L'état dépend des paramètres du plugin : | +| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | +| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | +| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | +| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | +| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/1 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++====================+==========================================================================================+================================================================+ +| -u | Indicateur à contrôler | snapshotvm | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ +| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | ++--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| THRESHOLD | - -warn | ++---------------------+--------------------------------+ +| | | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +Contrôle d'un datastore +``````````````````````` + +USAGE +''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastoreusage | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | +| | - « used » : l'espace occupé par le datastore (en octets) | +| | - « size » : la taille totale allouée pour le datastore (en octets) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 20/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-usage | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 80 | ++---------------------+--------------------------------+ +| CRITICAL | 90 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + +DATASTORE I/O +''''''''''''' + +Fiche d'identité +................ + ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Nom du plugin** | check_merethis_vmware_datastorio | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | +| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | +| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | +| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | +| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Interval/Retry(min)** | 5/5 | ++----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ + +Attribut du contrôle +.................... + ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| Attribut | Description | Exemple | +| | | | ++=========================+=====================================================================+================================================================+ +| -u | Indicateur à contrôler | datastore-io | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ +| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | ++-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ + +Le plugin a également besoin des informations sur le daemon « centreon-esxd ». + + ++---------------------+-----------------------------------------------------------------------------+ +| Option | Comportement | +| | | ++=====================+=============================================================================+ +| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ +| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | ++---------------------+-----------------------------------------------------------------------------+ + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + + +Création d'un service et/ou modèle de service +............................................. + +Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). + + +Définir les macros suivante : + ++---------------------+--------------------------------+ +| Macro Name | Macro Value | +| | | ++=====================+================================+ +| DSNAME | | ++---------------------+--------------------------------+ +| WARNING | 100 | ++---------------------+--------------------------------+ +| CRITICAL | 150 | ++---------------------+--------------------------------+ + +Création d'une check command +............................ + +Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: + + $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ + +L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + + diff --git a/connectors/vmware/doc-en/images/archi.png b/connectors/vmware/doc-en/images/archi.png new file mode 100644 index 0000000000000000000000000000000000000000..82dca91fec4159d8be96155e65412aa0fd645059 GIT binary patch literal 29775 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 literal 0 HcmV?d00001 diff --git a/connectors/vmware/doc-en/index.rst b/connectors/vmware/doc-en/index.rst new file mode 100644 index 000000000..8f840209e --- /dev/null +++ b/connectors/vmware/doc-en/index.rst @@ -0,0 +1,24 @@ +.. Centreon ESXD documentation master file, created by + sphinx-quickstart on Mon Apr 22 11:17:38 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Centreon ESXD's documentation! +========================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + installation/index + exploitation/index + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/connectors/vmware/doc-en/installation/index.rst b/connectors/vmware/doc-en/installation/index.rst new file mode 100644 index 000000000..03e2ed3f4 --- /dev/null +++ b/connectors/vmware/doc-en/installation/index.rst @@ -0,0 +1,184 @@ +============ +Installation +============ + +Prerequisites +========== + +Software Recommandations +```````````````````````` + +The "centreon-esxd" connector has been tested on linux systems. +Installation on other system is possible but is outside the scope of this document. + +==================== ===================== +Software Minimal Version +==================== ===================== +VMWare SDK Perl 5.0 +Perl 5.8 +centreon-esxd 1.3 +==================== ===================== + +Hardware Recommandations +```````````````````````` + +Hardware prerequisites will vary depending on the number of monitored hosts. Without configured, no checks are done. Minimal used ressources are : + +* RAM : 512 Mo (May slightly increase with the number of checks). + +* CPU : same as poller server. + +Centreon-esxd Installation - centos/rhel 5 systems +================================================== + +SDK Perl VMWare Installation +```````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay + + root # cpan install Class::MethodMaker + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + root # cpan install SOAP::Lite + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +All SDK prerequisites are installed. + +Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) + +Install VMWare Perl SDK:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Addtionnal Modules Installation +``````````````````````````````` + +Some features require additionnal prerequisites. + +To send data to a syslog daemon, the " Unix::Syslog" must be installed :: + + root # cpan install Unix::Syslog + +To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Reboot your system to complete. + +centreon-esxd Installation +`````````````````````````` + +Download « centreon-esxd » archive, then install :: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Configure "centreon-esxd" daemon to start at boot :: + + root # chkconfig --level 2345 centreon_esxd on + + +*"centreon_esx_client.pl" is the corresponding nagios plugin.* + +Centreon-esxd Installation - centos/rhel 6 systems +================================================== + +SDK Perl VMWare Installation +````````````````````````````` + +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. + +Installer les pré-requis CPAN:: + + root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite + + root # cpan install Test::More + root # cpan install LWP + root # cpan install Net::SSLeay + root # cpan install LWP::Protocol::https + + root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz + root # tar zxvf UUID-0.04.tar.gz + root # cd UUID-0.04 + root # perl Makefile.PL + root # make && make install + +All SDK prerequisites are installed. + +Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) + +Install VMWare Perl SDK:: + + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # cd vmware-vsphere-cli-distrib + root # perl Makefile.pl + root # make && make install + +Addtionnal Modules Installation +``````````````````````````````` + +Some features require additionnal prerequisites. + +To send data to a syslog daemon, the " Unix::Syslog" must be installed :: + + root # cpan install Unix::Syslog + +To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: + + root # cpan install DateTime + root # cpan install DateTime::Format::ISO8601 + root # o conf make /usr/bin/make + root # o conf commit + +Reboot your system to complete. + +centreon-esxd Installation +`````````````````````````` + +Download « centreon-esxd » archive, then install :: + + root # tar zxvf centreon-esxd-1.X.tar.gz + root # cd centreon-esxd-1.X + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/centreon/lib/centreon-esxd + root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + +Configure "centreon-esxd" daemon to start at boot :: + + root # chkconfig --level 2345 centreon_esxd on + + +*"centreon_esx_client.pl" is the corresponding nagios plugin.* + From cd59d4ae5733368371ecfdb33ffe136fada6c7b4 Mon Sep 17 00:00:00 2001 From: Stephane Duret Date: Fri, 21 Jun 2013 15:40:00 +0000 Subject: [PATCH 038/447] Installation finie et Exploitation en cours 21-06-2013 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@56 a5eaa968-4c79-4d68-970d-af6011b5b055 --- .../doc-en/_build/doctrees/environment.pickle | Bin 43441 -> 55525 bytes .../doctrees/exploitation/index.doctree | Bin 341484 -> 410975 bytes .../doc-en/_build/doctrees/index.doctree | Bin 5558 -> 6186 bytes .../doctrees/installation/index.doctree | Bin 31121 -> 31184 bytes .../vmware/doc-en/_build/html/.buildinfo | 4 +- .../doc-en/_build/html/_images/archi.png | Bin 29775 -> 25993 bytes .../html/_sources/exploitation/index.txt | 40 +- .../html/_sources/installation/index.txt | 111 +++--- .../doc-en/_build/html/_static/basic.css | 2 +- .../doc-en/_build/html/_static/default.css | 2 +- .../doc-en/_build/html/_static/doctools.js | 16 +- .../doc-en/_build/html/_static/jquery.js | 158 +++++++- .../doc-en/_build/html/_static/searchtools.js | 364 ++++++++---------- .../doc-en/_build/html/_static/sidebar.js | 12 +- .../doc-en/_build/html/_static/underscore.js | 50 +-- .../doc-en/_build/html/_static/websupport.js | 2 +- .../_build/html/exploitation/index.html | 50 +-- .../vmware/doc-en/_build/html/genindex.html | 7 +- .../vmware/doc-en/_build/html/index.html | 14 +- .../_build/html/installation/index.html | 129 +++---- .../vmware/doc-en/_build/html/search.html | 8 +- .../vmware/doc-en/_build/html/searchindex.js | 2 +- .../vmware/doc-en/exploitation/index.rst | 36 +- connectors/vmware/doc-en/images/archi.png | Bin 29775 -> 25993 bytes .../vmware/doc-en/installation/index.rst | 10 +- 25 files changed, 550 insertions(+), 467 deletions(-) diff --git a/connectors/vmware/doc-en/_build/doctrees/environment.pickle b/connectors/vmware/doc-en/_build/doctrees/environment.pickle index 22474718113e27fd68404a8b0bec9516aeb1207a..72be606ccf1663290f3fef01cd1c363cbf26fa4e 100644 GIT binary patch literal 55525 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 literal 43441 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

          %#ON{H?F|yTIcZ=ssZNfNxvW2W=TWA%xeGVA3B; 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 @FVtA4N)u`}jcjRX9f{I`+cytEA*OL-dG2r6 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

          9{h2h~F;9n>s36#Fou4+B9-Yr#>{ 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 E2V%GDcK`qY diff --git a/connectors/vmware/doc-en/_build/doctrees/index.doctree b/connectors/vmware/doc-en/_build/doctrees/index.doctree index 62710a3d7f8535f68e49ca783f066598b558d2e8..62ef966d439f963b1a3972602a219c4b4cb6b016 100644 GIT binary patch literal 6186 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 Dd|w7? literal 5558 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 K9`IWq%={nn1=#-p diff --git a/connectors/vmware/doc-en/_build/html/.buildinfo b/connectors/vmware/doc-en/_build/html/.buildinfo index cd98838b0..8748161eb 100644 --- a/connectors/vmware/doc-en/_build/html/.buildinfo +++ b/connectors/vmware/doc-en/_build/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 5c34505a03d196bacf5235352ea2ec0d -tags: a205e9ed8462ae86fdd2f73488852ba9 +config: 32c42c8fca5663d8b06feb85adcec649 +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/connectors/vmware/doc-en/_build/html/_images/archi.png b/connectors/vmware/doc-en/_build/html/_images/archi.png index 82dca91fec4159d8be96155e65412aa0fd645059..f83c5281e36dac30d5c47b4ad131dd03a9807390 100644 GIT binary patch literal 25993 zcmb@tWmuKb7A;IlcS%V|Nq090NOwy&0@6sgba!{Bbhpyo4blxt*Ik}-zVF}tclYzi z24t^y#f&k>8Z%T;UJ?b701*NL0_BsGxH1F;WGwjp2p$T2J()Uh1aFXz%95fGRpUg5 z;0G9U5jhbEh}vkRCqr29Gs0IXEk_6l)V_cJAb;7Fn1EjrIDOP~Qn530ay4`?g-|rK zv~^;X|ENmp!p6wK$imG0*C7`I!sPCgxQMEo-f1SRF17;UuiL2nHjLN=OeGB20t^fo zCG;5d1jY}r{ir8rXJ?Ej!ZkS1wO9zXd@tv9TqE}M{&4GL7vtxDuw2bu&G(GDZbwf} z=r2idadFlAFwFkFiDCMrI14)e4c%;ZxQ!O#`#Ly)ft7tCboD%AZbkhrp~*;q=%uvg zZITcUcJEbYBH<(zJ$RvmPZiiLRxwtkW<8^MC<#uknKv~MQuG$tov*7rK7U%E8V?o| zP$D2`#46D^jk&v`F$>acDQtj&FizP>zcYn zd~fZqr}wvu-*yTj{HD7SI)iEKy6U)ypg4H2GL_wrQJo>cv!D|UQq{il5>BJtqKcMh zhlQaz-7Xog{CS87igqDs7xe0Rr{gMhfAN=RIhVl9%j0z`#1+0E15u&5>)XN@EZvRs zHH?D@&3BjPj<1wo1n@D@LaF_Yf51ih_p6Xyc2|$!v%Nc8bhTObT!f+Q?0AGA_74i0 z+oYf|6Y>4SdfZ#yAB&QJW-Y0(rB^5#jOPuNHD}t%KS&y4K zxvi!r>^2OutL@f%j+XqyCdr60Bjtje42bA81}gN0d`_JYoM)Nh_Vywk)zXHdQmX! zo#=sdBQokQV3?`{Ywkcgzp}prtJ4E)bYtgt4Hzi5>?{Sgz}KrvuJECl8;VwhH*B!X z2-j*iQ|6t>JH;UI{q#h&K9YPkpAb9r4G(^raG{Z*AqV>$ah*hv_Qr^g z`J{5d&6=JE+AOu290@;+)?;QzSLe5Ib&)Rbmr;CHT;bq{URt(t=Ev>SgM{Mm(JIF$ z-Yg~E@A%L(bK-!#6C@l(Y2~bhYs9}z<3%$>@^yBeCX#C5vHOo539NSFsrxA&$de92 za?mPBqKNXTn$5R8Mw7yl4&b9HrFnQXHR!185@-*A?f+V)VkT1JENDZ2@-0VF-(XAx zPhay*pi+9dDXzGh2GwX_f|tCPyd<({pSYi7wjORSvG)pRdxHfIg?}`xxT*Wi_n^Lx zfD2P`U>S5T%*Q?RYu`rZFWo+!?Ji{y{z>}$R*=kR%nXyIYdGEV-_8Py+32}i;5s)* zbs?_Vk!FOk#tW8f=Cz;y{TZ(LeCk7|8_vzEs`xlUPbIK~^^}%_r%42eemI@moM4K7 zZiVBM5(HjqT)m_JEJ*7A-CG&n!`1FcG>K42BCE*oLbbln^TYN19}+6LtTdH(b>@^56eWqTFFI{5HtC!;;vYW_^!H=q;8@3!!CU=syEL*Y++|i+sgAw9z3^z8>$%IxBIG4TL$0h?F!JHT zITxB`wchHec9U&pLBUQi3SmwKSPi3YGx}z;wZ?s4xtprHySsq_X@jyOF|SjJTDkh0 zH*X$q&x_;Aa6wpC??7jVo|~IXX3&wSe7)V6E|iIkj5N%xuXpP4hwZM|-rkl==QK4p zH#adM67+1=X|g5eb6Ndiid0Wz_#KTzFb6vNoq+q5r#zSg$tQ$M8_B zw>bV) zH|O$sd1CzBT5r2XV4B9$vketfO$dGQs`9hiG z&60&`A0Z?&J-w{5va<5>;~bFyQmi|qP>2tfmX;PWKY#vwxVsa6>vq20VZBf#qDH3Z zPunASLA%-A695N2n2?Z=a}@*6pbMYB++?@WV6CCu4WEdIfzjgq`~d7IC@}DykhiQ& ziD-Xn3icO0PuJZyqxAHCM`vqoU#A6qUWk%N_}xfpX|+|w<%!3~=ruR{6*C$Q)kgg- z;I|19;B6GNw6rugnUS`+Nl86^+wJV`&J`<=)FT@hv8DpM?53v)!9o^&8`8@zzjE>N z{CI)s;81cHL}vBp;=&i!AgQJ0+wL9%e6O%CsdlgdN*+VKZX$D?8;2RLI`QDopKk`# zCmW%xa>Q-TAThXY%7s{wU{Hqe+00YAz{dZ`YNE|P-`?R%Btoqt*k_e@KmYb zOLGptr(AEt-uJ(W$XeLO)NtF8CHChUN15=NDWTA!@VIj6`%g#@Q|3_4V}_~O-5N6lhWT}bi2L`I3orK z?+j#QhR5@j!bBGSBIMt-K-Bn(U4JrYJPflL5)$GI%fZpm+}w;D#!CA<&Y;$SMJ z!R1u@+qZ8=5REw&QgCL41qCs`RA=x1?ECd%Z!P+_+ANFvIIuPSf4gunQ>-xQuhU?K z6G)wb^s2^UeRr{iuH4fLqK6^eBI3wb>_F8Jtr#59H}Gi&H50%cxksT|T3Vb>7Gv4& zj_1lX!0aY_e#FPeM@OScGchvWTwe!Wl+l_+zGdm1m_Wm=((gj$({29h*YVtiL#HmA z$_k4M(#=J!$L-lHqK>ekj*gDiu50h;_FRgVrt^CXv7wNKrzTn1$g4ar$w zmyDK{`_&f5&!0a#J2|1(J^Vd{j+E=3Z?^ya_xhR)D`c=a_4;g$4+{%ROswypc?yEK z1pGVlr;c#GvbJ`s-9{%89wST@WF2WOtr>$}`&%nk%V`SDU|$&-8SCCa1PIm-A3n@B zUF(>6J>4luNSOWp89B?V^DCO&HqBOf%f-pQF8HgljF1<~xJ2CDiXqOG@CC zNqzmLsNcU2kTyljgfq#Jw}y{}aO`dap@oRgG(-hvKPMQz5un+1SXi4Cdn~Wk^l(Icu1RMe~_BIbFb?(%}A{g*k;_&>|(J7nUQ< z^3OE92PYGQ$^jX;)+r}o=d?ebsfeh(2Tzc$Xugc@!%bA?x;Kh%)e-mK6UJ5dLjUiq zd&|)Nx5b**A}Lz!1pgwlAUs>RhOwEU;T)Wy*`*cm&WZ=p|5|8}8cAU4K>2_2L%{!i zu-EM2@o_z1Keq)Fuj>CD_xM%%gVAwB*0 z{G5rN9=RkA1J{Kr1l^xGKEZ_fZOr!WuJislvDJbP*?;FTcK~as3bq0xeG~_K8{UXg zq=Mm(iGPiCOrGo6t3^~6VuuV|z07n?nMW9bVOT8_^T&a?>S zmq#Z{b(y@*P}-sJNNpT8y!n{vWw-497G#X5-$7)VGu`m?GMO*xzVK}%#-^lLilrqZ z`$^#glQOEuFn04dI`>r9-1hHint%sq_y8*lOYM&z{;+m-=fM4xS8527&(=GR4-XNF z6Pd&3WWkVJzi05t$ ze2XVjKb`0+Zg03{5I+9B7s~=}-j9&0POr-wC1bhGl}Vd{o<1QdNw3}lLwmrAotBX? zDm+|l0j4q`kxV_$FvOK4E}^}wNPV*XTU1q5Yt2_S6qGV#$ns8RYeT!&@n!c5L4V#x z^z2OO3_XzyEv=sTH>?e6gPN*p+Gb`7B-*I{F2Bvx_4MAg*JdoWi2xVj_Pk@(4lXhh z7KZ58zr4IW_>e2)^YZud67nYxH}_~7$H>A$GTRVES0_^MJ^!4&LoTrJ+N+U5qQ6LiO z)LYb=3}M#4ZuSIBiQO6*8|yTFX|bH43R$SHuP>5Ie-kOkJ>1(16~*hY1HVinGwHt( z&0#%nVHIbd+S=@l-Ck^*bOGl>|TcO-swtm>6{W9AeTkWhEt% zQIPIQr2EUDdn6%*7%m!RYBgVQe(7AEp&NZDbEm?_=PO_>sdZYtV6SDbi16+)qn;pv)hjw^{SA(F44uTLTnhm{t1 zb#;YKLzbI@#B%&IlJEfCf*ES>ouDUtZAxP!XAT23HJnRM)YP=HdGvwEXsgF9BQK)N zWXF6NpX8k0j(0?T0}cA0Jmz zQi9d>ze8dPPZ#X)xCJ=JQ&Dj;1mnE{&exwNtkrrQ(!_nZM)UF13X^1-P;+4Kx7Ik{ zhpfTar;)m-ZBLPONXnknMxml8bUFLQVk88;^I@_8#TIKH)?-s0wz+-{GZ%V!=SG?P z#%lG=ky-IM)0#K-&C|<|;?UTL9|^OE(v(*Vk?C3>0bt?cuGd>)X#=!ho}H}^9&W(% z{yp^O_2CS)CL=xl?A)Ay&x@z2nTW-FtFtu^4-dDR0gi*BiVAdCZly}Ge2_Y|nfhm| zv(=Uh+X>Q;aMN)pM|}J zr+iW7ln$@(DUU5gquOXyaQ5$-0G}{UlgjqsclYW)NV$n4`dklGE4lgfji-_cc)SQ-qjb(s#yXIM(N z^Mu{N={GTWFW_i<%r#j4L|b^dZA#_iT;(0wkot&3d*AsSOwckg2z@sCYkA+4iR7Dt4x8#IhzagoTK%D#w5D~>Mnk;;b*VPld%+>oL!gsE@pz@>S* zuSQCg3=8@!zDdDZTS`)gdjYw>+^{q?IM|X>e#$d+fVZdsrkj_P>~eT8BsiBqOHQ-- zbDPV*$>yYR%=W-?vzpUi9=$pIWgaS{b0}5zbDt{==d+!Hv5H!!Pbpo(?nWbYCF;{Z zT-_Jv-_Fl23?Uo7gM&LVq%kK2qtC|dW@{s7tSDE>KyGAZC7sA1g%GB-7O4Xzd6rq2 z67)n74(Cv5w8~fY=emUsMRxA)9>ttyq^$w={~xp^d)lGv z;g$5CIcdwnsH+UYkQ5jgc(TMVI%;LJj{0(AG379IK6t%2pY(4?RasdXmH7V->4cqt>_i7y zJ_?JMipMqMcYRPXb(?&~{_b-7HrfNCPB%i%(s{EQ040K$NrQy5FYn0ADwASA%~{M> zRl?#srb4t}HxDJ68wi6PupwitD$5haVfwcNtVTxj#D^u@E}t0f_tB5()77=gQ-d@Z zEI=IE(7y?c{-xCQZwszp5$Zsab9ne`X;tWF0no-s5<|Xv&7!E-)@n-%M@j0QC0Xuo zdfb>1e>p}HvG=HTRi9*L-m0qTNJ|Y44J!{IDMJ~~AEsctb-BBm*Bv^*s!lyUMa$In9wiX;g&bO2^8zM5i-@ZOVv4`xWcXPAweoaS zQ6;1@@z|(j375co3a1Fl)w%k_&*k$(W_}y>b_#upkzYWm$w(#fZszsTdao{x@2 zln>YGw{I-+HZ5RP)h;;ZA9Xq`k;_U8DYP={|60s#RuiKC!ysN)J43GL>q^Hb_it@M z75#K)KTfZq-{su_emjvZR1GW>AYAss+m$A}zP>(CK;K_%iE&dfF`a{A2HhpMHb0R~ z#9wwiOJGF6bs9wA^)4TMRaGajlwyT!<%)q@#XPaE3tC3pJlbD zQ?BQyVu9N%X)7yhONY_w#bCnMp$7l#d&D`BBR@Qo-FARDY*!NRi4Ci#bsW+%CkU{z z`uGha+)Vr5hNA>&sT9c?)@rJ&s}Bzk_`oaR<)%j{mT}sN^w2SDXa6BeaEk(uzTLXiy$MXzQFoLu+G>eOi^_DYl zra@^AF*mue@Ex&ReNj?c8j%}*1aKlC*PP9kVztY16S0L;-OZ6rh%i$4E$t{v>_E+= z?w-i@DPE7;tb2AP;hHxDG&ldqBUfuDr9?M7JtToX*Ju_Rdf#86(-%78x6^wXE8eq( z*bRl3`MlDY+nT0%OhxdY9r4#fuY<6d#Af*#JTg2C=z1y&3J8@+Vm5GWFx$c~Fr)qx z7PBQvG4L32pv=&y(1aWT43dbAm@n)Jv(tehe7*tPU;&_AXySpn>^*KvjTLbw%-nNh<#dGujk0r5^(UMU6CzGBMC;>{c#l1~-52~83DuAm#Jco< zE_-YxLr_{WRo0`=1#brMS0o|2FZ3N!tt*3cq-MDXZ(vwvXG>KK{eIGi z1TU_hS6uCYaj?O9A@7?*jI69IbDc%2 z`!#KQU#+fG9{ym1s(cpTZe$xDoN#+{bVUVwyp|%T`?{v8s)9!He_ep{?t9N82Tk10 zREHKtK@}RsJ3I1f9EU+?Ybl<(Fs2VvV6{!mG4m?QxoQDjw&;NN8C+RO*ZzQ2-`Pr!M0Lop*A zgkt&$qC58Z11cizb)u(d3ow8&JT;-i;guTIdOfxf4V#+=C2WBX8Rk~P`8YSXfBuM- z$MD=%+UV)&{pTnV&o#;M;$9B8I^6Bu`oq;U>1m9#mIUTn$;lbC>vO{J3SfFG)H0Nf+iq5J%k;M;Y(uliZDMd4WeBBb2U#VfO%V7yIvlScN{+lC4HR&%lk|Db{n)?3z`@U4j-o8F) z0@s=g9W(p#`g&|Ax^apTKvM=vgG0vBju%ompf?1`##ZAig5(0c4bL zGfa+O5#D6ML2u-c#1<(I-q5t~Jg%MSuMh<35x-Pq!m)C0eKj5Px)+?@-sgCl}D#DBe zQ_RA?9T5=$;3{A&zhi1tYQt_6g9uDTO`ZQuoJ7Fg#MrnGAr=B3AVptTQh!iNU2Fqm ztbvA6v4BIbsdn5SUrqJB`tygZeR^Txe6AdCUx_y~G_)J9-V=b^;W0Jzo$REf`7$*+ z8JQ743gxZSNsSH;`Z|yiOW$AZ%E-&3ss;y)1IQalE#)VStheV23H>vQ7>Nn})Heu* zL?9zza$ST!t+Hfxu3nAq2E7vGq=}~}-Rj4`TSdy(E^$T*TcsZbxxYn(Ar=h6BP=a1 z|8EB>vIH-r&7!J=DWfo2Y&BLNb~~w2#5jJG{jf+cO8Z}80{4~%ycq$0x>Bv(1~EHU zpW={Ert)IT6ZTgM!XqLmQe_Qsjn5yV6s3`rl%%jtS(UiyEkMp!ad+#X(_+qrO0-~X z(KEcBS?jVQ93Fyqot*vW>wrYF6849{9~U`ieFvE}UWeza>$tcBkeF?D%G>3zr{Q1U z2>}d*cpNgwT>e0xY5CKjo7`Sn67J=EsgC-;2?dZbC``teJBX@f>m+|(!nBO?M3a`s zECG`E4;EYR@POMlsAhdPU~$Zyp2Db@a~A%_!6qS2G@X0Ti#JV`(xK6bjEu7iz8B-i z^m`Jh*A;n)P8rhCw7oZ;)O%6+ZhtK(FHN8YYVz)%$H4qqQ;{F{B*4y$6z30h0j?57 z3c!*e$H|5WNwIXR9DHIa2ephTzu%Zyk9E8u;qevZA)H1=ZR{LmrYd!2H3Wd0{4XSO zbiWS5V|Io?crQHHK=WfpfUA+$p<|>{psthO_4{@!e%fT&<*gtF2hDKl=X$&Fi!-x7 z+r}GRUNRjvnwmb;XW@iUm;pTp!$AdDC-}tZEv;aE72=HVR)Q6fQM8bQlWH!06v@df zDHuB^Cs9F4pl3+-A*ccjNM0>`1zVuRzul>;iPN&KSM9ZOF$R6dL$)fbJymv@ypD!QUnq5QGB>*I7Rw{aOr^JINacI(fL_~2eQ0S}C~@wQ5*P0;ijXAY zx1ab}rzVO?N&aWB!b@BGx2hUaWCVmBG!D*3#qYQ}AVd@m%p9P5Nc)Lpo-X!kv@kGtARj9;!$fxq}jA!!A z5{3p1)ZsE^q$QuGuufjhesbVW_obkFKhpvZAouKjt$>aUVo@-w6r1! z59`H;J6aPHc;&yJRgxq$)qFmMdFPodoYKIDCTb1SWWB$_ z*+vYWbR&>q$99IF$|V@uDQS8qrViw9&PiUh6E_5oYHbRgwSWActlxxwbhW4Q=M-p`OPeX4FQ3%%RD|BFpE=I7+a(WigVR1g5(-L0?)+TP7ar>sDcXFo@RU{ zHr6dzZLK-U7nR)tWnHKgt!-`p+q9@n3pdCq5$tHaEYdTRgs}rf*cNFfMG`{>Pfv3^ z8pfgJSoO#>cV(vAe$x181)rIBJ5&1l%_M7veEb89luPD)54-g(mo+uQ<`Y@#Ez4n# z)^*=fKQeJ4S+TwD?CemC8BKN9%ZdKbcZ3$NVu-_esB>%C_?p|wJ49vPaBj*4PqH{W zR3C&)5qF4^tmOgM--85ysN*Ni?to*evG~Ac({~-tkkgE8j;77w##Ijox0qU;I_H=4 zXXEaQr7dEM^TVf(y$RyilO?vJ=bsNk^VRxY@>$#j*qav*g3n5B)GpdC4P3%A@s~2t zZ(>w%GR*#1l>Hd~dR1SU6sIG4k6NC6QM#-q#+ZK|KI?olR31cV&KBZc*&aVqj!dztAZcO0ajj4g<0|lRT5QMHPI& zRByK~0$FUUVj0ao`BgSD9RIyBMAOFb`TdyOI-X)7z&+)>eb>Wf7gu*__}p~}f*clW zTrl#Hi$OdC%sNOCV}r5px7sx)_F|iIG5XbsM@PSxatVA8N9&B) zXl94rghetn`X%AVfYdT9DV zWMTRo8Gh!Z&og25)qiHt5W`$PJ1{!+0lkKxbiMssoyk-^+0Z)~v*o1q$3Ej=h11%I zzc{y-%=-(ImA`*Q_gTK}*_-<2pHiK3usV%BIJZ9PX`vE1yyO1+NcuhYSh4ek>sf z<|vhhJghd^g1fBcI2obk2X#7c*^2fLq@$IYM|&S;|KPe#P)Ue~ir)=UNtT@Jt-SQb zFW)*&J-ygRf3~hvi9eZn19!62an1I4kD(bUA>{qU{nbE2JM8=}_9o-fYwqzUe%n`) zPj~ag847pJO>SSa(_((x{XJdb;?dFy3DQN_R>W`Fqor{%-k?I+*+%vfuJRVVYak$y zCMOS(78Ml*L?b8yFWTCi4yUQ)(qckogKGtOnz7|l8Mpz3P^QefS2X$$s&RzVbZVl~ zUwqdAG>k9>r98>{2PIrj~MPbVoNkl`!T$ryjWvl>5B8V4j4M{)29q_s$jEhKNMl?nse-y2&V9GTlkbFFB~TbL;#< z0dqyj$45{c<7#c`Y&5~&XQUu|badqYcw;m81SoW%8i;{%a8c~=UVeu>0tjg+8!`AW zEe6%O^wL`N=&&CnZ#t7>kFDPFC?eT>d`Zz@Gs|2uH!YFTt7KME)8EGvrR#86CwiN8 zviM_B-PKTI~tVjw{aH{IO4|(LHm^a;1>7_f}x4(`@ zhSc0zGt>vO&n}m#qpir=PMQdO~JuG77)!pfC zcQCW}G{R?bg?~@rUv03fh5r+ck#Fiq%UY;)o82Q1Cj$cC7^~{@duoEckG>H|c;hN` z&gDS9AnGVAANBMjECim%#RL_V{0qJKNAbaIQyra^lanu23qK1%sI*;cH&YZnA2R;3 zsgmy%)qeL|rO8_lF@tHbbXUA4dMX@m7Mke3gehCF(Dgj(>`SmFyz{6dpT?)qbalyw z2I9q99Cl~``CkEdV{!5FaE&Br?TbgzOT~dR^>JoJSjX=XCl|@+E4*3_1dxQmro_kl zWiCoP96_3^@4nr>Y~5J>0{?QgIWg+5UlSV;Nzp&ZmfKM@t}Pg(G3U|YBjs=W_;QnW z*(pu;la*(5`)1y*W z!dX`GSE?LcNW$~e6DSgQj{35?J@ACDIOs#&fB~rNcXngDTg`70;RVauI9WH>$-QXUYYyiBi zmc_Uo8(VRdQVv}ZrWQYCuHm?XN^W#fNN6&|Zv#|kXm8+_R^q+Xkl(O>P8aCZ-U=U+ zql52xdVcok+ff0Z`G#^0R*7GffjTItGn#B!J@?D@9y2E7l;Z5u z`rc9*d!e6`)FOvVW4Ds;M+MtrE$0KU1d^FDum2v-kd>0HXs8HXzxUJi?}AB9PY0Bw z{w(i-Nvb={C zMWwa8797SQ>;7A!8Mo$|^;c(^$E8Y0q_jC&5En~v#cBRg$;ctm69&9K~QdSxoc<0&`9V^Cn zLs*sE!DjjKl=o~^d3isKf1%ROxL1H$iCDmanR3W((I9=~mz9w6xoDA`vbah}=YApE z&!QvI;cZK*`1l~6^U(y8rCphlU)XcCop`wKG6nd$mzI7w?gP;hRAwm(PJ_p-?cHX^ zi7GeKQT8O_rjeZ9RUtH;@At3!lrw2UnC zwzt~pOcU1k_=)R|nQZIaqZ-~{GMHQGxf$i}rj=Gs>BeUI#B+xt)?;A%2B=LbRA3i0 z27dnRmE<&al5zX|8lx@+WsZB*NJH`+b%#q&I}HB%{rE{qcSWz`Lxuu@plXw?RSh-s z_|T+DzRz2Rav#(6eRW1gM!niE>P87NvO@XzAGXoWbM2^`*zhpp;{(Ybq<>v&=&+Ql zfnsZ%Pth70(t{gcIdL<-)8|#t^-R~))S(E&*lQrQw4r#euyPu0;%(O63|*^5HV2KJ%4MudfU#0}LS_aL2RRne%jO*-*5+G%%qH`g+E2-*hKrmoVNkJ#H7)$SCVxPX^g(dd}{fv?6ePEl6q zd8b(rtmb6PC{h9fIpU<#=N-oC!VeMIhQ=>TtXH~~aP^|#np`PLj)!N}*e#^YmW}pA zIVJ&~{alsgp|b2spEdmbotlvM$yaR$VW*mb82H`c4TpG>@F|l^jVpO9{ZN05s5-r(?D5VJaAG+-Z zw8h4cAP8UFf+FU*;~KhMd!eVE!7~;}Bn5JDriF}flg+RH;vcX6=@%mC>2A9pptlw9 zesUWhWwAGmn(}jZ{60yDJqWiK>(wN$j#<7J8;`5D%QUf8omo#vl+X9&fRy$&%^K8p zjq660|WmmBERzGfZ(8jz5yA|%oQd_{tBuYb6(4Hn=+x0Q)_M|j%mB8(?j)fq>jL;JGCiR zMZ-=sk>RZXxUg7F=|A|o;vC-A?xXwojc99ZqrToIC0p5{W^rBG?rs~S7Xy-ETIFGX z|Mz$1xga22bIxQ5&u?$nd2qK{J56tKp7~lEFNcb$Cz#d_^^woqBIUJdI@3>| z5X!zlT8x(XRiDi}M9lpvwk_XlM7>s%MZpl@?&_5ZZgRJ6wQ%!2EXj>Uu^-Nn_^0Lj zd^@^*pgUjM*%8@NEX(~PM3X;`hh5sn;5F&fRFvfqBwf;YC$N%@r_Eo#enHpS5*N>e z{m!!{*Jw;!AT#ecNavfcugi3GbyYR34Fvj%91(VwT0HhZul7Ocey*-O^bg^HApcYOy|zb79M%=$!44Ax1F=xv8-B0H znqR#i7~tIKkWui4bTuK>iq+9)R496(mLo{w2RFEg%3c2R@IWoLVugb8&uZ=2HMTrRsiabVhgg~BnBr!n`E(NH{c1J}OCMbv0Ed3=e()p~|5oc#HM3%vb z4UNk2Wkjs*4o#*`G1`IE{jCT%im>b4p&>}qpF$jj9JMbT&kg7Pi85QK*hYGLMccG^ z>fSL@zhit~6;xN86#0VE;*I+_{Z;Wj8uARRnLT5~l~R-Knl?-Fda7E=g4gud08)jP z2*2L?OY$0C+ZCxaC6OzQhF4NhAUR!kRYB%K z3sd5^Xk-RvG1@3*zZ@A`arBOC1w2E4KsukqUAg$N^w4a zNAm7!yb`dS#EV^UD34(%wGt(~^}cTjawQkG;I0~AbGp#g^|_xyMV;G?e1lH2W8Y-LQKW~e63B!rrT=spS?$BX&D*i zt(}gS)&5aO_`6AG)w2!x9P9gBj!$%H|ec*jpmw3ZH+vT5u+m^z^HJvD->RI9Cp2a0*@5 z3wbmI!B!?ruFeMP0V(Lj<$4JJ9q-epPrOmK{8Xi_OH8#AY|DOSsms`)rwYz?Ivb|pmnz&Ki zaaXoSoMD26WJjJGBp%&WQ%xxSQCs5%nnwO(!avN|vn z<@3~SEH4VXJZR2%;I$zluuxJ`UdkS6a^U>$b8KwZRqq4c#970=^qtfkr+kHkZi~oD zY0Zgi);r6di_L96^U@;L2I3=&eo|5umyPQ&I66Fpqy-62Rt*a2SmA#w15)u>#o`oL zDsv}IdEIc*q3e|v3&F07{Mu65CYD5Mcu}#>qROJp`8p}3&P;Ctwz!Nc7jlB=4KY69 z!x|cHb$LE<%>O4A{j+Y+^Ae`aQx_vsg^8x2xZ__$ep|!@>&MQiW{UM*%TURF6I)#K z`PccuB%8Lx7^%godY!F^0|A2v<+zfi87VnAZAeQ!K`WI)77?z5&)^wwGQd!HKiy5` zihT#1jY_F0=w0gDaImtb2E9_y9U~PI@`Sa(s`FTz@Hmt%0sV?v5 zvX64YKnv?TOe%5+RDO7jx;c#?!ktM>Q~+W9(2(M&dt*G&@r5T-5H%^@Qj>F{_Q#ip zA3~9G?B}01lyo!ZbTz;+Xp0nvmQ|HTl*#u;$P(98@y?SGulCLA@X}bMQ89E)+e}Kp z_dh{Hm6RDI9)e^lOZ5lL5=i)g5_@=X5Q1~y*DsB%1Lv_c4$wD7$6sDh03+xRBtgBb zJEhgt8$kTPpwlS)1hmEU6cqKY=X&+j=h~pv>G9^YG%<~akB^YH?#t2-6hcn=&#mm_ zLX*WObqC(&0Ua;&xJXLK^1lK9CdwV3oP2vYQw%gu$w^7_Da^Uf$MdddF=!3JnLJp5kcr%` z1!55{pnU|$VC?sFcg&KYbylOruP!eSS6kQ`dc9|PU=%ZQkYPCdo^zW41DfBW2UOQU zHr=mYshykVn-eT79FoF~r>EE94x1`mB9$(I!g35Kn_1qrI_IO=QVXCh_!mJyqfa;9 zuKm&|N|1TzQz>?fEo940@(kj=wGs>p2mtPTMJ1%PR39qK7K#*>F@J4t1y>!~K;fl* zuWE$X8L^?^aya8@Df$V_*^>)Rt~;mEW+WR$@XKNi(06o0brY|1Sx9vFyuRBe1s82f zN>h`Qia;M>X?a-nxvf_)EG$eiipY@Ub^~-_P5Gfq03rq`NLQAYLPJ6zqDf=>=pjHT z0sr}H5l#uT$RUZo?M6*21WNA7FM-=dvZ?-?wi)p(E)m&YHFBop=~WkX=!PdRa92Ge1x}oEfe)zk*orDIs*p{Jd3%MYDMS1+Vto8i;WwjDPa?B7TYYevyYMUkH$dr0fo?w& z6B8iK5Vz?Y-ChHWM4wZ5J7+oB&3HV|m=||f`7s=~2hVh$HBOQV73*F_%7Ba?#|*>O z9DM+F-NkLx2oRpZhF{YJq9AHM@}tBR8-r><2?(v>mxNQ z=vSCpE>ESRXo_!6cAWT{B5trExZiczHQ0RS0VpRP#YqtrWw7a>*A?TCtBk*iY3 zst*H3T^LRi9u-xB3_0W{{VWb_S(w&)$tdwrC~^x6i?;*>!GVFJ89Z1~yJom1NH%@I z*>m$_NQct}y?E=<$%28Ks=y=zom+59VtRVGOH^cJPzLB%tEi};r;5ja_fDR;Zyr?4 zep(PBHzGKyEkf4Q1)nCT#Yg_TeCyq?d#-VAQu6lBbAojRYQgdB<)73d-Dq9jpDSr7 z5;wjqMmHnv01f!x+p_(DY_{6OA8~IzPYYC?bp8^oEc?6*E3W5#q^5`y@&4KW!7Fb6 zAyTt^jR%57MoK)xfO(dKeG6IqdMg~1Ag!K^27e3? zIjK)Q+Tg&zz~bUtTqr20jLb|Wa*OMuImPU<6j&XMI=xO$1ir5a2$3R-Fi71MSppt; z;vZ@V{V#Ozaq*C&iS4aD;$&HdcRm9-GB{AyQF0FA{ z4&Y?}-R1r4Pu8Kfkt#}$0f5su!u>6vcGn^f^W%((8HrsB<}QwrZU@*Zl;fYd_rE=B zSXt4+5HvP6&brTy`nzd;{Ajw-=~c7Z;o+Jy0mOQwcX9FYVxx$Nhz`!qULbgQe#-&k z8D>Vk_Ce5KIX^cCD{lj?T|rAHs7ixK>VOQQk17X&UThZJOl4mF{>5cET>$!0Xw5)Z zVvGuwot+&L5)%BzIJgl;0>%~8f0W8$x6W@N1)>QNxi|>IKrNX2KWCw1S^w^`?dNAS zMdl7|{GiPD+^{)9fPpb=!m24ME)H?YoZdTAC$Li}rv1LQY#*?t_6f;Yriiufl;gE0 zSk=p`d2*Xj{q*>zW8*I4jL^Z9^lk8?({|_6!*;j@O@~dwOOwGp2DBgkY*ihC?pv1p z?V0$~v(F`0meU6C8oyAR-U%^=&O_=7C1z)%bk%%;d88@o_gJKXUku{<{oz zyD<3I0eWRX=N>l*a1=(nMXU2Mu1Uzw!NI}#Ik-mSy=xHD`Hz_y%?H5ULTb|OuT07F z?8JE{>#dpe1rQ@5>M6oKH8ARpS}v#~cpoI-gx>!SjSFj%aD4iW(}DJ~g;QK3Y-5Ov z6&0j!msBENhw7DU1G+=i*-qZJZ6Z(7+TRzVp2hNheh|sa`YpVe$sU05I{f{Tf*zI)i)q;j|C2Qq=a>jolAd zRC^N)4C0bHt9$yR!7kjVB8D`=+yde0VnF12P!elyW>Z3Q&$+pG=*Wgdg@mA=pmjxF zK%hIcFZZWrBm5B4AG+UqADeHp0~1D=r5`3RN*3?1 z7x=O|$yj)+%j5ieKnw1~n4Bn@m`~U=P%Zjjy>uL>h5mn9JIlBzyRPjclF}^*(jwi6 zga|`-=YU8{NSDAxmx#1)Sy6^Y>_NA>at7exC-In-k-woj@Xv`}&pT%a?Vg8#~Zw~{nJYO5cY72J)boCK+Fsg@}Mb`QRY6L!@aF@iWD^3FPRoFwT zy}1@aw!xJJ$t!o*GL>PdkCj&2{Hx&9EGd&xqKsE9O^q&r!Iq*PqcVimd<=(r@)28` z(`#*k%P&d=Y7mc=t!93$*kbHOf54sEB1U_lmyS{`VIrl0BV0H>j?L$NdCVM}CbD_p z_V4B6jinc+mO2jw6<1_%oxSG~P$c^4kA~8+w05#%{$Qr+nu-OFWwDbeu#RRVPv z9d~ir;$%HMqbN1@TZ!&(l-Eh6rL5Qzu=ZGgZqwzwORa0~bo&gZPH)#XtptO>7Bbb{ z+JctoDbWkJnLv%&pLLamE_hQ)zJ@k$f@%2s ztK4nTdHD=20%DHO5}NOL=nj_cNk~>)j?9FTM5kMkN6}4DI9PJRib7SMI^5nlCncl% z+wJSFOm7Y5mgZ`IKGO%OC?i%_VWGRO?w44?a=-B7NENgK;0P`*4(md*rA^UOg@KN4 z`$K8-pmeeNoA7<9_X+0e)`obh+XFq|8`H>p^R<`;trQj&`6oiNMLb_c_fAXt)nM)r zoTh2SlNYhJWLYMXXdh}|>ALi^I?0T=bZJpBTM3hIZvU*hxX>8B?))1?@cDiB^) zo*ev|{>SOFblo{ZW=K=*cb*+^Z6$IQwNEuI{&8lbw8kGs1pRWXUOX|-FRFPIE>mh@ znORWXU1sRHzaEMyN)V$hQq!CPZL%hMyA*G(d0Iw!r#rX)cv637L&34nqxrKtz2Pa9sgIcimB$+tGWkH=mCZghk)v8=OMIpL5z@~((Js{^ z7#B5ZiO&bx$-O2>Wz`+GfCeHvd&-nYZ(6dcgy$L@U=9A(l z{2xsRKc!VT+oJgEJaEtBjb46*dXS5dm~I^2GU=; zZh};_#KD~bS*8`Wk}PL>HElN~Cb}diwE0_D7NbO2nS-_;r80&7q5EEifNDnXCv5kC zLTFK-1o#1RDr zA^j~!w)c0pPoF;JAom^#MvbymC0yMFzJ?93Yfa7R3n9m#Wz{}17Mu8BqG!(6tHUmT z?aZ%whpnM?_NZ`!WxRF^m%_)v9KtM6Q%o;B3gKVfQ zZZsj@iC%->=b2$Sr~NHh6;bWa+F1CUApY&&BXdw10E&+QCTtB20`$@E zeeM>#agUjVcnY>AcA8Dr(UGeJ&C*^+=rMLNRUVxw6k!twTr3%$e8j}x6%}#VazAc% zp{*2D;9j#oe_rv1yA8WyhY_wSi}!S87NVvRs>0TxpPouB|F?-)k#9E)5n>Tvvldw* ziO5IWli;)aIqhB*ho2lX6`)(P^N5Nu;{>hQCM2b`xT`N=QW~+)2y9oQh{v|*QOii_ zuf5j@f=6(__VUhKTKi4psn?#Kr?Cy~8=bqW4!<$na!Ks(YT0*p3WR3{pqK#t?%NO+ zhLK_Sk&myPjZKMdrId=mj3=?PYek=%n|oLwnuiDBzL^ISyJ$6h5aXb{r+cLvZy>?4= zS%-QNs-@iFTi`Lo;jfX36PXfV1=0HPWb~rRd1taOU-ElqQL()9E5^e{>`!eb<2c2& z>$jVun8}&(W|hgDsTw0aIVMdWLw%7MRuEhLxc??vI+Y5Cr-e_kDR;vL)L8G({1t<4uFDLWuHWeAy(g$GgXA$B*$WuW z7EBYZ#k-q@n+SqBs%%jU3QAjlrUc(Kh|ZOsIxyrJfQ2Si`B`wgQ*2VEF*Zc(!@~q` zUCG?nZ|-ZVc#jD^E~bGmq$K`tfq!2GiAJy)$6kSq!fDAsRN*Pf%D&vMt}XhIg2ylO z6XcZO$`3H1)K z-`)}vThxylN-^XUhk2dKKI1o1C>?DJfUvJa=I3Kizxm(ej>)lGo8s*sDlN&I=5E+H-6;MMuYK=Vry3_OINTMY(9yvedBO;$t` zjH(t`Ir-ejM@PS79Qv*KMi4T_d?wmDsC2tb;oO6K?I%o9qp^D_;DEB7Jv`L%>iL-C zs(ksXD3`fxSbp{P>rs<*3IFdOA9<%LDQUZ@BjEr;Qc@I&Nl|!spne3rchtwgy_ToA zk#P3_zIk!(m|KR=EvuPGw!z%t_iUzjZYKoTpvm4G9PY`)C@`wfK_cdDERV)qF=TsW zX5WbG1V0d6ezZWLa;q|vWGFR5s{jYfd{M`BgNoSdv0TA3a`K((GFt^QAj`2xUR_&* zkPWg-vBH5z%wQ*e8fR=Lo6YS@{3WgkiEC#G zhK~y;cuqBW0g{vR+Z06-YH^J!Ngepigqcle!#FRG08#VKw5)p`7|@Jr3;H(`(1t6_ zUFY?U(BaV0{$gCe zcC2BoJ!M8Dd?2Okh&O0fJyLzaWW*GzuFECJm#0zs;mOC3+dDg2mM029meXv@4{Udv zVkb#~fvwL-vtGjRDPEOM`$p~Zo4dEt%D(kaNfG=h5{rjQEx{hJU1|0_DhOSzSDHdf z%&962#%{yiiDrYVg7?E%FWM-aU=REForJ%B=%s^hv^j=XZ$-vLS~A@&P(0jy_t5qT znoQv}|0NLE_OYA83BRdE9zu5f06P+3GLY_UT{E*G0fCb0OQv?dfsqRFX32NFofFin z`@9U+ewQr$33|NyG&39fb!FXa;WYu(Uwkmfw$(+|oIG3q`8cx$`{$>-pqS>XW{LgA zD}N%iu_x1+#uhEz{8I`Fl`%+VOIIW2fFst)1kw^Eyz7~g>-|wzi;mS0RBz_Eu7z4L7MI{G zu@}^XI~#K4kiCpw3!%we*kHEUtb;t(FMmkieyHm**1Hd9=ph_Th2q?a_+dj ze!gos@%cRSvhrYESXRbMqXA1327~3{Vnl1XDJkq(RH5iUNf{Kw!vp=gbuMD!YCb;g zIp27cRChjGo?yvS7cOgZ0N5llC?8OBNgJtrD?aq@vZtGFD9Re~z-nlB3sNq-N4<6& z{*{W*K|0>UELQlUE5A~U@j(J>dFA3y&6_j({psi+3`tjNN_PF>{#wQdON5mo^ zk|xL@B`he-#H#OR8lYeB)yszVn{-N@MSVwQAJJ#;Qp?}Z0aFtC{9PC*V&W$P3q{!lI%Bjbn@3p^%p{eXG$M0k{yo{C{oK+4rMss}|yCp6YrE4b{ z7h@udVlY$ZZ`GOxm&2i0u?FUuK2q*_Lrm?brbHSkIuCTnd^1y9m14Rh(g3hjRegc* zdLLms+2MoHsiMpp17CWztI@DydqT?4Hh~h;2wX~Uw-gN1TynoRf}Q55JuO&DaGW9S zQ-lVksQO!}cpwaoq%5syfJAgLMkJX>x|2k3YDKQB3{Dj9tmZNqrll1@2dT=Z(Z1*n z^g8vD6&Lzt;TSp2*C9L5`z&%xT2O6mX|fRl>{tUvYMkBgt{m22g&v5!E+oaKlo=+}@G|wC#cY?qY+XCft zLQ7H#3JH+<016$Tgf#nJ9wW(sv=Sbs_gOSQg({5TUYGHyC%-=d=vBdIqJl|nouAcj z5hjZBgUvKfk8IEfrPf^p9Pn6w&(fImI%a0rfX?=h^^KK^5FtJtF$t#ER)zB~A?|hD z^l@l|jnwi`{1RaEjZC=uw9R97(M5zPQU{peAosvMm0X`Y4DVw&LUho3K?UFv^o03#xn#4C4rJk#~G%*TSUtHO?m32vI2 z4ppm5;xGTBjQ11{odXSr*Ut2NO{2h4#C?V@LKTOLQ|^cP372F}Ec9?UkB6S)5FlPB ze};ul@pM`6(I@_*i!`Ux%lP79Y1MLmyowS*@n(GDBr$HKBJb5-0Eg1-I)R{C=z7Uj zS9#cq_T~G)6{H>%2k1sXV`dV{3G|%!%P}r4bj}xXjC1Q>pQs{iZ=zY6yl2xQLk((% zan(vTDarNq@uWbpJ=nD~6h}vZmY67VV!UsY>iKf@0sa4W~)pG8K4UBy{4Wc-9!5Jx|h8|9Y?2gun?b8L#Ia1?rwdA z<;3dg&g7Cm__zY|xlc8{V3Ps~Vtf2scOnLY8B^I<9IDF9^P<6KkZsUb5_z?~0vb}x zb{gO{=L7T=2t~93Mg6RH(wnIegRh^WH|Er^cR1(+HK}G>M3*W#bI$A3615`D@f+B9 zb~0WeXC2s{o~t@dumcL5pxfAd7(6jiEZQ(95MQT3c2ESC|L`*SF=2&(BR(tM?$dWM zU#!%xF@N`$O7q8-|B}D7)%eT>u5w%|uB#5st6}`_I2Z{%X>Wj4?vKk`$9(c~3yYT- zfO4XeA{c+Gj_b_JH%XOOfy=r_H4PQu>Ml}0`<>ihs@)RhB7oF$@YlsHS_8Ha(rF7^ zw$ZN4$(c%-5_O#;^O$A0D#M!~}fIK2^simP* zJNgY3Wh5^pp@sN>yRIhPZ%v7kN{8oc^UdC_W%jQW0tS!mE%DEWB~*?}4so3uXr1k_ zj(p#st2#IRjb}hUhH0|(j1u$4hKaIvZsY?+E&a0C^w5N!{YiP{!(4JhaV7@7`cy0O znO_`-112pt_GSH|f`Th(iAh9XlF7o*H89K#CW=Jz^6<7O$!*Lw7V?>Z?};7P?KK1e zoYWk0V9J|4=p%cvxmtkHIT>km4g}qrQStF#UYrhC6?Dx(oAe=u)L=*fzkNK3Ny%2w z(0H-(Vk&llP(x{U5lMN-wv!mF^Q>Uf~Co%*<+k{71&Yn|R4S9h&|T7%$U%R!C`SvoyEy(2y= zOa8|R+S-*yb&~5;_o6OG!bOvx7E{q5e912E&S#(Gx6vJ>r)4*HbX5D#y+HPibGp+h z#@jpTXQJE5UTl1HLea(%ohyyN#+le|llwP@0k!gnfp$zBil`h}O_zu342j!Hawi3oh8EI$;LBiP>F9*~Gpm;vi;p{EBkX_x{8gR9S_7*q|2Y-{`bpNZjcxCZ*235W>Ud!7 zeGSOL2M^Io%Kf>8%3vg(d=b`7tYUHNh7hqu#Y%=58G?stutoLcD|V~pssv=`xE;EPp(?GY1Gn+7gx^A;gGXT9D7bjfToj$}YF zJtV9dRFnb65n$<(%q1G7l$D>0xBr?~5XA^q*VMc^-+KZ85(xmA|Am-rZ#E2F?1OXt zwvk6aG-YVV+yK~zt8HY2(k;6><%G|3$k^zRAx!0Wb;>IKOg2RPFZ_ul^>fC_$d3;d z+Z`J{i^sN;s*c71g%SR)FfY%{-kzF}@DR9Odp!VS3-BCc@hLGsyja8i@U2EWs1q|YT7OxaZDE6~HcOMIMD>BPe zr&iUpsDpYY+3nn>2li*UFVMp#`iT+9AruNlKhAA8Yk$YAMkt9^6@{Y@j$AJ|jTlTF zY^E!c(AuJ7zr+Lj*I)4b$5sGr^!((+{2N4w(XTYqPGod=q1j$;*@Wtwj>#i>mi%3i9nyk(Hom^81ymBhXlo=Mg3h>MAO-2?`?lmY@wv-_D0~sqQ5eTlrKe z!jv!4)N$2h&S6}DB6F+bHmIF8yK#tWxh(P#WmK8G0)gl51HuAJ6KiBzuyCadZDtlg zl-CPWy0ufv5sFVvb*&UIW65}50=-v%Oz``kUz$ZRsa}JQbi>Gkkpcb#Keo}b`uY@+ z&96EXgHlVR`<9ln3)Q+PtW5>>2qk5XY7GdGv1KZ8mu(@PVoO7aS{eJQTZoFP;> z(WKc68qLX%PYK~g>qAQ+A;M!L<;^wnS5N}4A+P{*X1*)RSNMFJoE#fbg@DB5-v0(S zchx!$JpI65s#tlW3dCGN2?$RDTm6k_etbV4J05fea8WDrzuIP#>+&?NT6~*mHN5mz zpPyx!&9L6(sg9^`n(LskpA|e6+OVj z+p8Rq{^5G2Pq4%pDf02-C^6|mB43RV^6xk5z_k7fsoBlZw?;@^Sr6t>r@JsP z)3tcoL3Ef|APN5NDzOyc&3)^fn4LZHnOA;_vNHBg5Ki?OJhE@XX)hd27AGDd1;_t> z2-yZZJv{{`$p0dmJ64efoJq}0od160f6O=jUxg+A|1akM_5SXfR%l69xbb$q5d2dL Oih_))G)&4g=>GsL(zAX5 literal 29775 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 diff --git a/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt index c5657eb15..34cbfba2f 100644 --- a/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt +++ b/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt @@ -2,41 +2,41 @@ Exploitation ============ -Présentation de Centreon-esxd ------------------------------ +Centreon-esxd Presentation +--------------------------- -Principes Généraux -`````````````````` +Generals Principles +``````````````````` -Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. +Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter. -Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : +By default "centreon-esxd" starts at least two processes (named "handle-client" and "handle-vsphere-xxxx") : *« handle-client »*: - *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + *Process waiting for requests of "centron-esx-client.pl" clients.* -Voici le fonctionnement : +Steps of operation : -- Un client se connecte. -- Le client demande un indicateur de supervision sur un VirtualCenter. -- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». -- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». -- Le processus « handle-client » fourni la réponse au client. +- A client connects. +- The client ask an monitoring indicator on a VirtualCenter. +- The process "handle-client" sends the request to process "handle-vsphere-xxxx". +- A response is sent by "handle-vsphere-xxxx" to "handle-client". +- The process "handle-client" sends the response to the client. *« handle-vsphere-xxxx »*: - *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* + *Process responsible to connect and to keep opened a session with the VirtualCenter. To ensure quality performance, a cache of datas description is created.* -Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. +Then, this process gets back the VMWare indicators creating a subprocess per request. -Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. +Centreon-esxd necessitates the utilization of one (or more) VirtualCenter. It isn't possible to get back informations of an ESX server directly. -Voici un exemple d'architecture éclaté : +This is a example of a fragmented architecture : .. image:: ../images/archi.png -Mode de fonctionnement -`````````````````````` -Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). +Operating mode +`````````````` +The "centreon-esxd" program only works in "daemon" mode. (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. diff --git a/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt b/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt index 3534d2c3c..fd8b2f207 100644 --- a/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt +++ b/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt @@ -2,42 +2,42 @@ Installation ============ -Pré-Requis -========== +Prerequisites +============= -Préconisations logicielles -`````````````````````````` +Software Recommandations +```````````````````````` -Le connecteur "centreon-esxd" est testé et validé sur des environnements Linux. -L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Solaris, Windows, ...). +The "centreon-esxd" connector has been tested on linux systems. +Installation on other system is possible but is outside the scope of this document. ==================== ===================== -Logiciels Version minimum +Software Minimal Version ==================== ===================== VMWare SDK Perl 5.0 Perl 5.8 centreon-esxd 1.3 ==================== ===================== -Préconisations matérielles -`````````````````````````` +Hardware Recommandations +```````````````````````` -Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n'effectue aucunes vérifications. Les ressources minimales sont de : +Hardware prerequisites will vary depending on the number of monitored hosts. Without configured, no checks are done. Minimal used ressources are : -* mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). +* RAM : 512 Mo (May slightly increase with the number of checks). -* CPU : même pré-requis que pour le serveur de collecte. +* CPU : same as poller server. -Installation de centreon-esxd - Environnement centos/rhel 5 -=========================================================== +Centreon-esxd Installation - centos/rhel 5 systems +================================================== -Installation du SDK Perl VMWare -``````````````````````````````` +SDK Perl VMWare Installation +```````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. +The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. -Installer les pré-requis CPAN:: +Install CPAN prerequisites :: root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel root # yum install perl-XML-LibXML perl-Crypt-SSLeay @@ -54,41 +54,39 @@ Installer les pré-requis CPAN:: root # perl Makefile.PL root # make && make install -Nous avons notre environnement prêt pour l'installation du SDK VMWare. +All SDK prerequisites are installed. -Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_). +Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) -Installer le SDK Perl VMWare:: +Install VMWare Perl SDK:: root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz root # cd vmware-vsphere-cli-distrib root # perl Makefile.pl root # make && make install -Installation de modules complémentaires -``````````````````````````````````````` +Addtionnal Modules Installation +``````````````````````````````` -Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : +Some features require additionnal prerequisites. -Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: +To send data to a syslog daemon, the " Unix::Syslog" must be installed :: root # cpan install Unix::Syslog -Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: +To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: root # cpan install DateTime root # cpan install DateTime::Format::ISO8601 root # o conf make /usr/bin/make root # o conf commit -Ensuite redémarrer votre système. +Reboot your system to complete. -Installation de centreon-esxd -````````````````````````````` +centreon-esxd Installation +`````````````````````````` -Télécharger l'archive de « centreon-esxd ». - -Installer les fichiers:: +Download « centreon-esxd » archive, then install :: root # tar zxvf centreon-esxd-1.X.tar.gz root # cd centreon-esxd-1.X @@ -101,24 +99,22 @@ Installer les fichiers:: root # mkdir -p /usr/share/centreon/lib/centreon-esxd root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ -Activer le daemon « centreon-esxd » au démarrage:: +Configure "centreon-esxd" daemon to start at boot :: root # chkconfig --level 2345 centreon_esxd on -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* +*"centreon_esx_client.pl" is the corresponding nagios plugin.* -Installation de centreon-esxd - Environnement centos/rhel 6 -=========================================================== +Centreon-esxd Installation - centos/rhel 6 systems +================================================== -Installation du sdk Perl VMWare -``````````````````````````````` +SDK Perl VMWare Installation +````````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. +The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. - -Installer les pré-requis CPAN:: +Install CPAN prerequisites :: root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite @@ -134,41 +130,39 @@ Installer les pré-requis CPAN:: root # perl Makefile.PL root # make && make install -Nous avons notre environnement prêt pour l'installation du SDK VMWare. +All SDK prerequisites are installed. -Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_) +Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) -Installer le SDK Perl VMWare:: +Install VMWare Perl SDK:: root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz root # cd vmware-vsphere-cli-distrib root # perl Makefile.pl root # make && make install -Installation de modules complémentaires -``````````````````````````````````````` +Addtionnal Modules Installation +``````````````````````````````` -Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : +Some features require additionnal prerequisites. -Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: +To send data to a syslog daemon, the " Unix::Syslog" must be installed :: root # cpan install Unix::Syslog -Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: +To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: root # cpan install DateTime root # cpan install DateTime::Format::ISO8601 root # o conf make /usr/bin/make root # o conf commit -Ensuite redémarrer votre système. +Reboot your system to complete. -Installation de centreon-esxd -````````````````````````````` +centreon-esxd Installation +`````````````````````````` -Télécharger l'archive de « centreon-esxd ». - -Installer les fichiers:: +Download « centreon-esxd » archive, then install :: root # tar zxvf centreon-esxd-1.X.tar.gz root # cd centreon-esxd-1.X @@ -181,11 +175,10 @@ Installer les fichiers:: root # mkdir -p /usr/share/centreon/lib/centreon-esxd root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ -Activer le daemon « centreon-esxd » au démarrage:: +Configure "centreon-esxd" daemon to start at boot :: root # chkconfig --level 2345 centreon_esxd on -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* - +*"centreon_esx_client.pl" is the corresponding nagios plugin.* diff --git a/connectors/vmware/doc-en/_build/html/_static/basic.css b/connectors/vmware/doc-en/_build/html/_static/basic.css index a04c8e137..43e8bafaf 100644 --- a/connectors/vmware/doc-en/_build/html/_static/basic.css +++ b/connectors/vmware/doc-en/_build/html/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/connectors/vmware/doc-en/_build/html/_static/default.css b/connectors/vmware/doc-en/_build/html/_static/default.css index e534a0780..21f3f5098 100644 --- a/connectors/vmware/doc-en/_build/html/_static/default.css +++ b/connectors/vmware/doc-en/_build/html/_static/default.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- default theme. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/connectors/vmware/doc-en/_build/html/_static/doctools.js b/connectors/vmware/doc-en/_build/html/_static/doctools.js index 8614442eb..d4619fdfb 100644 --- a/connectors/vmware/doc-en/_build/html/_static/doctools.js +++ b/connectors/vmware/doc-en/_build/html/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -32,7 +32,7 @@ if (!window.console || !console.firebug) { */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); -}; +} /** * small helper function to urlencode strings @@ -61,6 +61,18 @@ jQuery.getQueryParameters = function(s) { return result; }; +/** + * small function to check if an array contains + * a given item. + */ +jQuery.contains = function(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == item) + return true; + } + return false; +}; + /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. diff --git a/connectors/vmware/doc-en/_build/html/_static/jquery.js b/connectors/vmware/doc-en/_build/html/_static/jquery.js index 198b3ff07..7c2430802 100644 --- a/connectors/vmware/doc-en/_build/html/_static/jquery.js +++ b/connectors/vmware/doc-en/_build/html/_static/jquery.js @@ -1,4 +1,154 @@ -/*! jQuery v1.7.1 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
          a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="

          "+""+"
          ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
          t
          ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
          ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

          ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
          ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
          ","
          "],thead:[1,"","
          "],tr:[2,"","
          "],td:[3,"","
          "],col:[2,"","
          "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
          ","
          "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
          ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
          a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

          ";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
          ";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
          ","
          "],thead:[1,"","
          "],tr:[2,"","
          "],td:[3,"","
          "],col:[2,"","
          "],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
          ","
          "];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
          ").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
          "; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/connectors/vmware/doc-en/_build/html/_static/searchtools.js b/connectors/vmware/doc-en/_build/html/_static/searchtools.js index 56676b25b..663be4c90 100644 --- a/connectors/vmware/doc-en/_build/html/_static/searchtools.js +++ b/connectors/vmware/doc-en/_build/html/_static/searchtools.js @@ -4,11 +4,38 @@ * * Sphinx JavaScript utilties for the full-text search. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ +/** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + +jQuery.makeSearchSummary = function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
          ').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; +} + /** * Porter Stemmer @@ -193,38 +220,6 @@ var Stemmer = function() { } - -/** - * Simple result scoring code. - */ -var Scorer = { - // Implement the following function to further tweak the score for each result - // The function takes a result array [filename, title, anchor, descr, score] - // and returns the new score. - /* - score: function(result) { - return result[4]; - }, - */ - - // query matches the full name of an object - objNameMatch: 11, - // or matches in the last dotted part of the object name - objPartialMatch: 6, - // Additive scores depending on the priority of the object - objPrio: {0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5}, // used to be unimportantResults - // Used when the priority is not in the mapping. - objPrioDefault: 0, - - // query found in title - title: 15, - // query found in terms - term: 5 -}; - - /** * Search Module */ @@ -244,13 +239,8 @@ var Search = { }, loadIndex : function(url) { - $.ajax({type: "GET", url: url, data: null, - dataType: "script", cache: true, - complete: function(jqxhr, textstatus) { - if (textstatus != "success") { - document.getElementById("searchindexloader").src = url; - } - }}); + $.ajax({type: "GET", url: url, data: null, success: null, + dataType: "script", cache: true}); }, setIndex : function(index) { @@ -278,20 +268,19 @@ var Search = { if (this._pulse_status >= 0) return; function pulse() { - var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; - for (i = 0; i < Search._pulse_status; i++) + for (var i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); - } + }; pulse(); }, /** - * perform a search for something (or wait until index is loaded) + * perform a search for something */ performSearch : function(query) { // create the required interface elements @@ -311,46 +300,41 @@ var Search = { this.deferQuery(query); }, - /** - * execute search (requires search index to be loaded) - */ query : function(query) { - var i; - var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; + var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"]; - // stem the searchterms and add them to the correct list + // Stem the searchterms and add them to the correct list var stemmer = new Stemmer(); var searchterms = []; var excluded = []; var hlterms = []; var tmp = query.split(/\s+/); var objectterms = []; - for (i = 0; i < tmp.length; i++) { - if (tmp[i] !== "") { + for (var i = 0; i < tmp.length; i++) { + if (tmp[i] != "") { objectterms.push(tmp[i].toLowerCase()); } if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) || - tmp[i] === "") { + tmp[i] == "") { // skip this "word" continue; } // stem the word var word = stemmer.stemWord(tmp[i]).toLowerCase(); - var toAppend; // select the correct list if (word[0] == '-') { - toAppend = excluded; + var toAppend = excluded; word = word.substr(1); } else { - toAppend = searchterms; + var toAppend = searchterms; hlterms.push(tmp[i].toLowerCase()); } // only add if not already in the list - if (!$u.contains(toAppend, word)) + if (!$.contains(toAppend, word)) toAppend.push(word); - } + }; var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); // console.debug('SEARCH: searching for:'); @@ -358,51 +342,89 @@ var Search = { // console.info('excluded: ', excluded); // prepare search + var filenames = this._index.filenames; + var titles = this._index.titles; var terms = this._index.terms; - var titleterms = this._index.titleterms; - - // array of [filename, title, anchor, descr, score] - var results = []; + var fileMap = {}; + var files = null; + // different result priorities + var importantResults = []; + var objectResults = []; + var regularResults = []; + var unimportantResults = []; $('#search-progress').empty(); // lookup as object - for (i = 0; i < objectterms.length; i++) { - var others = [].concat(objectterms.slice(0, i), - objectterms.slice(i+1, objectterms.length)); - results = results.concat(this.performObjectSearch(objectterms[i], others)); + for (var i = 0; i < objectterms.length; i++) { + var others = [].concat(objectterms.slice(0,i), + objectterms.slice(i+1, objectterms.length)) + var results = this.performObjectSearch(objectterms[i], others); + // Assume first word is most likely to be the object, + // other words more likely to be in description. + // Therefore put matches for earlier words first. + // (Results are eventually used in reverse order). + objectResults = results[0].concat(objectResults); + importantResults = results[1].concat(importantResults); + unimportantResults = results[2].concat(unimportantResults); } - // lookup as search terms in fulltext - results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term)) - .concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title)); - - // let the scorer override scores with a custom scoring function - if (Scorer.score) { - for (i = 0; i < results.length; i++) - results[i][4] = Scorer.score(results[i]); - } - - // now sort the results by score (in opposite order of appearance, since the - // display function below uses pop() to retrieve items) and then - // alphabetically - results.sort(function(a, b) { - var left = a[4]; - var right = b[4]; - if (left > right) { - return 1; - } else if (left < right) { - return -1; - } else { - // same score: sort alphabetically - left = a[1].toLowerCase(); - right = b[1].toLowerCase(); - return (left > right) ? -1 : ((left < right) ? 1 : 0); + // perform the search on the required terms + for (var i = 0; i < searchterms.length; i++) { + var word = searchterms[i]; + // no match but word was a required one + if ((files = terms[word]) == null) + break; + if (files.length == undefined) { + files = [files]; } + // create the mapping + for (var j = 0; j < files.length; j++) { + var file = files[j]; + if (file in fileMap) + fileMap[file].push(word); + else + fileMap[file] = [word]; + } + } + + // now check if the files don't contain excluded terms + for (var file in fileMap) { + var valid = true; + + // check if all requirements are matched + if (fileMap[file].length != searchterms.length) + continue; + + // ensure that none of the excluded terms is in the + // search result. + for (var i = 0; i < excluded.length; i++) { + if (terms[excluded[i]] == file || + $.contains(terms[excluded[i]] || [], file)) { + valid = false; + break; + } + } + + // if we have still a valid result we can add it + // to the result list + if (valid) + regularResults.push([filenames[file], titles[file], '', null]); + } + + // delete unused variables in order to not waste + // memory until list is retrieved completely + delete filenames, titles, terms; + + // now sort the regular results descending by title + regularResults.sort(function(a, b) { + var left = a[1].toLowerCase(); + var right = b[1].toLowerCase(); + return (left > right) ? -1 : ((left < right) ? 1 : 0); }); - // for debugging - //Search.lastresults = results.slice(); // a copy - //console.info('search results:', Search.lastresults); + // combine all results + var results = unimportantResults.concat(regularResults) + .concat(objectResults).concat(importantResults); // print the results var resultCount = results.length; @@ -411,7 +433,7 @@ var Search = { if (results.length) { var item = results.pop(); var listItem = $('
        • '); - if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { + if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') { // dirhtml builder var dirname = item[0] + '/'; if (dirname.match(/\/index\/$/)) { @@ -435,18 +457,16 @@ var Search = { displayNextItem(); }); } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { - $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt', - dataType: "text", - complete: function(jqxhr, textstatus) { - var data = jqxhr.responseText; - if (data !== '') { - listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); - } - Search.output.append(listItem); - listItem.slideDown(5, function() { - displayNextItem(); - }); - }}); + $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + + item[0] + '.txt', function(data) { + if (data != '') { + listItem.append($.makeSearchSummary(data, searchterms, hlterms)); + Search.output.append(listItem); + } + listItem.slideDown(5, function() { + displayNextItem(); + }); + }, "text"); } else { // no source available, just display title Search.output.append(listItem); @@ -469,32 +489,20 @@ var Search = { displayNextItem(); }, - /** - * search for object names - */ performObjectSearch : function(object, otherterms) { var filenames = this._index.filenames; var objects = this._index.objects; var objnames = this._index.objnames; var titles = this._index.titles; - var i; - var results = []; + var importantResults = []; + var objectResults = []; + var unimportantResults = []; for (var prefix in objects) { for (var name in objects[prefix]) { var fullname = (prefix ? prefix + '.' : '') + name; if (fullname.toLowerCase().indexOf(object) > -1) { - var score = 0; - var parts = fullname.split('.'); - // check for different match types: exact matches of full name or - // "last name" (i.e. last dotted part) - if (fullname == object || parts[parts.length - 1] == object) { - score += Scorer.objNameMatch; - // matches in last name - } else if (parts[parts.length - 1].indexOf(object) > -1) { - score += Scorer.objPartialMatch; - } var match = objects[prefix][name]; var objname = objnames[match[1]][2]; var title = titles[match[0]]; @@ -504,7 +512,7 @@ var Search = { var haystack = (prefix + ' ' + name + ' ' + objname + ' ' + title).toLowerCase(); var allfound = true; - for (i = 0; i < otherterms.length; i++) { + for (var i = 0; i < otherterms.length; i++) { if (haystack.indexOf(otherterms[i]) == -1) { allfound = false; break; @@ -515,107 +523,37 @@ var Search = { } } var descr = objname + _(', in ') + title; - - var anchor = match[3]; - if (anchor === '') + anchor = match[3]; + if (anchor == '') anchor = fullname; else if (anchor == '-') anchor = objnames[match[1]][1] + '-' + fullname; - // add custom score for some objects according to scorer - if (Scorer.objPrio.hasOwnProperty(match[2])) { - score += Scorer.objPrio[match[2]]; - } else { - score += Scorer.objPrioDefault; + result = [filenames[match[0]], fullname, '#'+anchor, descr]; + switch (match[2]) { + case 1: objectResults.push(result); break; + case 0: importantResults.push(result); break; + case 2: unimportantResults.push(result); break; } - results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]); } } } - return results; - }, - - /** - * search for full-text terms in the index - */ - performTermsSearch : function(searchterms, excluded, terms, score) { - var filenames = this._index.filenames; - var titles = this._index.titles; - - var i, j, file, files; - var fileMap = {}; - var results = []; - - // perform the search on the required terms - for (i = 0; i < searchterms.length; i++) { - var word = searchterms[i]; - // no match but word was a required one - if (!(files = terms[word])) - break; - if (files.length === undefined) { - files = [files]; - } - // create the mapping - for (j = 0; j < files.length; j++) { - file = files[j]; - if (file in fileMap) - fileMap[file].push(word); - else - fileMap[file] = [word]; - } - } - - // now check if the files don't contain excluded terms - for (file in fileMap) { - var valid = true; - - // check if all requirements are matched - if (fileMap[file].length != searchterms.length) - continue; - - // ensure that none of the excluded terms is in the search result - for (i = 0; i < excluded.length; i++) { - if (terms[excluded[i]] == file || - $u.contains(terms[excluded[i]] || [], file)) { - valid = false; - break; - } - } - - // if we have still a valid result we can add it to the result list - if (valid) { - results.push([filenames[file], titles[file], '', null, score]); - } - } - return results; - }, - - /** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words, hlwords is the list of normal, unstemmed - * words. the first one is used to find the occurance, the - * latter for highlighting it. - */ - makeSearchSummary : function(text, keywords, hlwords) { - var textLower = text.toLowerCase(); - var start = 0; - $.each(keywords, function() { - var i = textLower.indexOf(this.toLowerCase()); - if (i > -1) - start = i; + // sort results descending + objectResults.sort(function(a, b) { + return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); }); - start = Math.max(start - 120, 0); - var excerpt = ((start > 0) ? '...' : '') + - $.trim(text.substr(start, 240)) + - ((start + 240 - text.length) ? '...' : ''); - var rv = $('
          ').text(excerpt); - $.each(hlwords, function() { - rv = rv.highlightText(this, 'highlighted'); + + importantResults.sort(function(a, b) { + return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); }); - return rv; + + unimportantResults.sort(function(a, b) { + return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); + }); + + return [importantResults, objectResults, unimportantResults] } -}; +} $(document).ready(function() { Search.init(); diff --git a/connectors/vmware/doc-en/_build/html/_static/sidebar.js b/connectors/vmware/doc-en/_build/html/_static/sidebar.js index 5adf89522..a45e1926a 100644 --- a/connectors/vmware/doc-en/_build/html/_static/sidebar.js +++ b/connectors/vmware/doc-en/_build/html/_static/sidebar.js @@ -16,20 +16,12 @@ * Once the browser is closed the cookie is deleted and the position * reset to the default (expanded). * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ $(function() { - - - - - - - - // global elements used by the functions. // the 'sidebarbutton' element is defined as global after its // creation, in the add_sidebar_button function @@ -156,4 +148,4 @@ $(function() { add_sidebar_button(); var sidebarbutton = $('#sidebarbutton'); set_position_from_cookie(); -}); \ No newline at end of file +}); diff --git a/connectors/vmware/doc-en/_build/html/_static/underscore.js b/connectors/vmware/doc-en/_build/html/_static/underscore.js index 5b55f32be..5d8991434 100644 --- a/connectors/vmware/doc-en/_build/html/_static/underscore.js +++ b/connectors/vmware/doc-en/_build/html/_static/underscore.js @@ -1,31 +1,23 @@ -// Underscore.js 1.3.1 -// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore is freely distributable under the MIT license. -// Portions of Underscore are inspired or borrowed from Prototype, +// Underscore.js 0.5.5 +// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the terms of the MIT license. +// Portions of Underscore are inspired by or borrowed from Prototype.js, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: -// http://documentcloud.github.com/underscore -(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== -c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, -h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= -b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== -null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= -function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= -e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= -function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, -c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; -b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, -1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; -b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; -b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), -function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ -u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= -function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= -true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); +// http://documentcloud.github.com/underscore/ +(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;gf?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)}); +return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length); +var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false; +if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length== +0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&& +a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g, +" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments); +o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})(); diff --git a/connectors/vmware/doc-en/_build/html/_static/websupport.js b/connectors/vmware/doc-en/_build/html/_static/websupport.js index 19fcda564..e9bd1b851 100644 --- a/connectors/vmware/doc-en/_build/html/_static/websupport.js +++ b/connectors/vmware/doc-en/_build/html/_static/websupport.js @@ -4,7 +4,7 @@ * * sphinx.websupport utilties for all documentation. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/connectors/vmware/doc-en/_build/html/exploitation/index.html b/connectors/vmware/doc-en/_build/html/exploitation/index.html index 8982a0e59..3cdc39ac9 100644 --- a/connectors/vmware/doc-en/_build/html/exploitation/index.html +++ b/connectors/vmware/doc-en/_build/html/exploitation/index.html @@ -1,3 +1,5 @@ + + @@ -47,36 +49,36 @@

          Exploitation¶

          -
          -

          Présentation de Centreon-esxd¶

          -
          -

          Principes Généraux¶

          -

          Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d’un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter.

          -

          Par défaut, « centreon-esxd Â» lance au moins deux processus (nommé respectivement « handle-client Â», « handle-vsphere-xxxx Â») :

          +
          +

          Centreon-esxd Presentation¶

          +
          +

          Generals Principles¶

          +

          Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter.

          +

          By default “centreon-esxd” starts at least two processes (named “handle-client” and “handle-vsphere-xxxx”) :

          « handle-client Â»:
          -
          Processus en attente des demandes des clients « centreon_esx_client.pl Â».
          +
          Process waiting for requests of “centron-esx-client.pl” clients.
          -

          Voici le fonctionnement :

          +

          Steps of operation :

            -
          • Un client se connecte.
          • -
          • Le client demande un indicateur de supervision sur un VirtualCenter.
          • -
          • Le processus « handle-client Â» fourni cette demande au processus « handle-vsphere-xxxx Â».
          • -
          • Une réponse est fournie par « handle-vsphere-xxxx Â» à « handle-client Â».
          • -
          • Le processus « handle-client Â» fourni la réponse au client.
          • +
          • A client connects.
          • +
          • The client ask an monitoring indicator on a VirtualCenter.
          • +
          • The process “handle-client” sends the request to process “handle-vsphere-xxxx”.
          • +
          • A response is sent by “handle-vsphere-xxxx” to “handle-client”.
          • +
          • The process “handle-client” sends the response to the client.
          « handle-vsphere-xxxx Â»:
          -
          Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).
          +
          Process responsible to connect and to keep opened a session with the VirtualCenter. To ensure quality performance, a cache of datas description is created.
          -

          Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande.

          -

          Centreon-esxd nécessite impérativement l’utilisation d’un (ou plusieurs) VirtualCenter. Il n’est pas possible de récupérer les informations d’un serveur ESX directement.

          -

          Voici un exemple d’architecture éclaté :

          +

          Then, this process gets back the VMWare indicators creating a subprocess per request.

          +

          Centreon-esxd necessitates the utilization of one (or more) VirtualCenter. It isn’t possible to get back informations of an ESX server directly.

          +

          This is a example of a fragmented architecture :

          ../_images/archi.png
          -
          -

          Mode de fonctionnement¶

          -

          Le programme « centreon-esxd Â» fonctionne uniquement en mode « daemon Â». (dans le sens où il ne peut fournir les indicateurs sans l’utilisation d’un client).

          +
          +

          Operating mode¶

          +

          The “centreon-esxd” program only works in “daemon” mode. (dans le sens où il ne peut fournir les indicateurs sans l’utilisation d’un client).

          Lors de l’utilisation du plugin centreon_esx_client.pl, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans “/usr/share/centreon/lib/centreon-esxd” et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires.

          @@ -2191,9 +2193,9 @@ snapshot le plus ancien est plus vielle que « temps_courant – XXX 

          Table Of Contents

          \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/genindex.html b/connectors/vmware/doc-en/_build/html/genindex.html index 461f46511..67f65cb2f 100644 --- a/connectors/vmware/doc-en/_build/html/genindex.html +++ b/connectors/vmware/doc-en/_build/html/genindex.html @@ -1,4 +1,7 @@ + + + @@ -14,7 +17,7 @@ - - @@ -93,7 +93,7 @@
          \ No newline at end of file diff --git a/connectors/vmware/doc-en/_build/html/searchindex.js b/connectors/vmware/doc-en/_build/html/searchindex.js index 6a665ac86..d83bedd88 100644 --- a/connectors/vmware/doc-en/_build/html/searchindex.js +++ b/connectors/vmware/doc-en/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{"2iop":2,code:[],check_merethis_vmware_datastorio:2,trl_lun2:2,librairi:2,global:[1,2],troi:2,yellow:2,"\u00e9clat\u00e9":2,fourni:2,row:[],indicateur:2,"27iop":2,init:1,"surallou\u00e9":2,aux:2,valeur:2,"d\u00e9j\u00e0":2,sond:2,"valid\u00e9":1,"22743040o":2,sont:[1,2],garder:2,check_merethis_vmware_nethost:2,level:1,"d\u00e9marrag":1,servic:[],x86_64:1,visualis:2,"362747904o":2,"derni\u00e8r":1,direct:2,syslog:[1,2],second:2,pass:2,port:2,vmware:[],supervis:2,"_hostvcnam":2,section:[],quelqu:2,statushost:2,riops_lun1:2,communiqu:2,version:1,sur:[1,2],peuvent:[1,2],net:1,cela:[1,2],"charg\u00e9":2,"contr\u00f4ler":2,voici:2,snapshost:2,bodi:[],solari:1,"fonctionnalit\u00e9":1,modifi:2,valu:2,"m\u00eame":1,"tr\u00e8":1,search:[0,1],"v\u00e9rific":1,"r\u00e9cup\u00e8r":2,beaucoup:1,host:2,datetim:1,action:2,que:[1,2],environn:[],"risqu\u00e9":1,modul:[],souhaitez:[1,2],unix:[1,2],instal:[],total:2,"1773761536o":2,commun:2,lwp:1,pourcentag:2,perl:[],latenc:2,overhead:2,rhel:[],vcenter:2,type:2,more:1,ensuit:[1,2],riop:2,check_merethis_vmware_cpuhost:2,log_daemon:2,filtrer:2,check_merethis_vmware_datastoresvm:2,iso8601:1,warn:2,twl_lun2:2,twl_lun1:2,moin:2,cach:2,"rattach\u00e9":2,augment:1,car:2,uniqu:2,pour:[1,2],minimum:1,taux:2,nagio:1,root:1,"506574405632o":2,tar:1,requi:[],share:[1,2],check_merethis_vmware_swaphost:2,templat:2,critic:2,unzip:1,check_merethis_vmware_healthhost:2,"r\u00e9pons":2,traffic_out:2,suivant:2,gcc:1,refresh_keeper_sess:2,"totalit\u00e9":2,rapport:2,write:[],toolsnotinstal:2,optimal:2,xxxx:2,swap_in:2,mac:2,attent:2,mai:[1,2],datastoresvm:2,datastor:[],"remont\u00e9":2,souci:2,permet:2,light:2,timeout_kil:2,correspond:[1,2],allon:1,issu:2,inform:2,ensembl:2,make:1,"m\u00e9moir":[1,2],"d\u00e9faut":[1,2],offici:[],peut:[1,2],"00mhz":2,afin:2,"h\u00e9bergeant":2,kbp:2,jnh:1,"r\u00e9colter":2,"_servicethreshold":2,uuid:1,window:1,"\u00e9critur":2,memhost:2,nom:[1,2],non:1,"syst\u00e8m":[1,2],handl:2,dan:1,taill:2,devel:1,"\u00e9galement":2,effectu:[1,2],autr:1,optionnel:2,nou:1,"1jour":2,"bas\u00e9":2,critiqu:2,name:2,aucun:[1,2],temps_cour:2,"install\u00e9":1,check_merethis_vmware_datastoreusag:2,timeout:2,champ:2,cett:[1,2],espac:2,"cr\u00e9er":2,connect:2,"r\u00e9seau":2,distrib:1,our:2,"probl\u00e8m":2,variabl:2,respectiv:2,mettr:1,"nomm\u00e9":2,content:0,"\u00e9cout":2,traffic_in:2,centreon_esxd:[1,2],red:2,serveur:[1,2],"contr\u00f4l":1,check_merethis_vmware_maintenancehost:2,e2fsprog:1,qui:[1,2],org:1,selon:2,contient:2,libuuid:1,openssl:1,filter:2,liaison:2,yum:1,unknown:2,processeur:2,"r\u00e9sultat":2,"pr\u00e9sent\u00e9":1,check_merethis_vmware_countvmhost:2,mise:1,"pr\u00e9":[],votr:1,affich:2,donc:1,"indiqu\u00e9":2,crit:2,virtualcent:2,tou:2,ont:2,size:2,fonctionn:[],"_hostesxdport":2,mkdir:1,trl_lun1:2,nethost:2,"final":2,shell:[],option:2,"poss\u00e8d":2,cpu2:2,cpu3:2,specifi:2,cpu1:2,"d\u00e9pend":[1,2],date:[1,2],centreon_esx_cli:[1,2],ssl3_get_record:2,"00iop":2,older:2,wiops_lun2:2,wiops_lun1:2,timeout_vspher:2,ressourc:[1,2],sera:2,"red\u00e9marr":1,cpu_total_mhz:2,"acc\u00e8":2,aussi:2,myvmnam:2,"56196403200o":2,wiop:2,jour:1,lib:[1,2],min:2,hostvcnam:2,"d\u00e9connexion":2,libpath:2,fonction:1,deux:2,soap:[1,2],simplifi:2,macro:2,"sp\u00e9cifier":2,index:0,usernam:2,"configur\u00e9":2,plat:2,doit:2,dessu:2,maintenancehost:2,cpu0:2,"v\u00e9rifier":1,toolsnotrun:2,"class":1,url:2,request:2,snapshot:1,"_servicedsnam":2,"68705865728o":2,"\u00e9tat":2,vcname:2,"n\u00e9cessair":[1,2],"cr\u00e9\u00e9":2,text:[],session:2,threshold:2,identifi:2,trop:2,retrouv:2,xml:1,fichier:[1,2],menu:2,activ:[1,2],"cr\u00e9ant":2,"70148096o":2,"diff\u00e9rent":2,"s\u00e9par\u00e9":2,yml:[],count:2,cpuvm:2,ssl:2,mainten:1,"pr\u00eat":1,"t\u00e9l\u00e9chargement":1,vsphere_serv:2,"172032b":2,"2147483648o":2,snapshotvm:2,grai:2,bad:2,write_r:2,"\u00e9vite":2,"caract\u00e8r":2,swap_out:2,riops_lun2:2,"643976658944o":2,"_servicecrit":2,"recommand\u00e9":2,fail:2,sen:2,xxxxx:2,sorti:2,nombr:[1,2],vont:2,"_servicewarn":2,attribut:[],parent:2,check_merethis_vmware_memhost:2,officiel:1,comm:2,avon:1,cli:1,plugin:[1,2],"sp\u00e9cifi\u00e9":2,etc:[1,2],erreur:2,rend:1,login:2,"allou\u00e9":2,"d\u00e9conseill\u00e9":2,makefil:1,"d\u00e9finit":2,perfdata:2,"d\u00e9finir":2,linux:1,connexion:2,aller:2,json:[],"pr\u00e9sent":2,difficil:1,datastoreshost:2,cpu_tot:2,xxx:2,demand:[1,2],viperltoolkit:[],toolsvm:2,"entr\u00e9":2,"ais\u00e9":1,"_hostesxdhost":2,error:2,"1408f119":2,stdout:2,envoy:1,expat:1,"4561920o":2,"allum\u00e9":2,"00m":2,vou:[1,2],libxml:1,archiv:1,cento:[],conf:1,chkconfig:1,situ:2,par:[1,2],develop:[],log_crit:2,author:1,perform:2,balloon:2,memvm:2,"pr\u00e9senc":2,"ex\u00e9cut":2,"imp\u00e9rativ":2,traiter:2,grand:2,lite:1,http:[1,2],ouvr:2,nic:2,nicnam:2,vieux:2,moyen:2,"h\u00f4te":[],com:[],notr:1,"r\u00e9cup\u00e9rer":2,traffic_:2,client:2,command:[],titl:[],san:[1,2],programm:2,"g\u00e9n\u00e8re":2,protocol:[1,2],physiqu:2,tcp:2,processu:2,ayant:2,connecteur:1,bit:1,"renvoy\u00e9":2,site:1,virgul:2,toolsold:2,exempl:2,"cibl\u00e9":2,bloc:[],log_facil:2,enfin:2,check_merethis_vmware_snapshotvm:2,adress:2,esxdhost:2,bin:1,xxxxxx:2,format:1,read:2,mot:2,cpan:[],remont:2,check_merethis_vmware_datastoreshost:2,healthhost:2,password:2,daemon:[1,2],header:[],fournir:2,"d\u00e9fini":2,dsname:2,noth:2,collect:1,"pr\u00e9alabl":2,page:0,"r\u00f4le":2,www:[],besoin:2,swap_:2,interv:2,seuil:2,"14344192b":2,log_mod:2,hostesxdhost:2,bloqu:2,"n\u00e9cessit":2,ouvert:2,tmp:2,est:[1,2],swaphost:2,octet:2,esx:[],retri:2,avoir:2,minimal:1,machin:1,plu:2,sensibl:1,ancien:2,usag:[],virtuel:1,"test\u00e9":1,wget:1,"\u00eatre":[1,2],column:[],commit:1,"donn\u00e9":2,zxvf:1,routin:2,read_rat:2,vsphere:[1,2],son:[1,2],lier:2,"archiv\u00e9":1,sou:2,retourn:2,lieu:2,mymeta:[],testvc:2,log:[1,2],plusieur:2,support:[],logiciel:[],lor:2,esx1:2,interfac:2,comport:2,"1589248b":2,methodmak:1,usr:[1,2],lun2:2,lun1:2,pleinement:2,form:2,link:[],cpuhost:2,sdk:[],info:2,vive:1,temp:2,possibl:2,"default":2,avec:2,record:2,"cha\u00een":2,notam:2,vmnic0:2,"s\u00e9rie":2,user1:2,certain:1,utilis:[1,2],decrypt:2,lectur:2,"m\u00e9triqu":2,file:2,dessou:2,"mod\u00e8l":[],hostesxdport:2,commenc:1,"occup\u00e9":2,courant:2,check_merethis_vmware_statushost:2,crypt:1,seul:2,"_servicenicnam":2,normal:2,viell:2,test:[1,2],snaphost:2,architectur:[1,2],countvmhost:2,check_merethis_vmware_toolsvm:2,cpu0_mhz:2,hostaddress:2,"param\u00e8tr":2,check_merethis_vmware_cpuvm:2,lanc:2,niveau:2,exclu:1,ssleai:1,descript:2,check_merethis_vmware_memvm:2,"598016b":2,esxdport:2,"t\u00e9l\u00e9charger":1,cpu:1},objtypes:{},objnames:{},filenames:["index","installation/index","exploitation/index"],titles:["Welcome to Centreon ESXD’s documentation!","Installation","Exploitation"],objects:{},titleterms:{configur:2,modul:1,requi:1,"pr\u00e9":1,"contr\u00f4l":2,indic:0,exploit:2,cento:1,tabl:0,instal:1,"cr\u00e9ation":2,connecteur:2,check:2,vmware:[1,2],centreon:[0,1,2],reseau:2,welcom:0,"mod\u00e8l":2,titl:[],section:[],"mat\u00e9riel":1,logiciel:1,perl:1,health:2,rhel:1,optimisationd:[],document:0,memoir:2,attribut:2,machin:2,swap:2,statut:2,dan:2,usag:2,"identit\u00e9":2,"pr\u00e9conis":1,"h\u00f4te":2,"g\u00e9n\u00e9riqu":2,mainten:2,cpan:[],datastor:2,fonctionn:2,countvm:2,sdk:1,vmtool:2,esxd:[0,1,2],"compl\u00e9mentair":1,optimis:2,command:2,troubleshoot:2,"g\u00e9n\u00e9raux":2,list:2,virtuel:2,"pr\u00e9sentat":2,princip:2,snapshot:2,mode:2,esx:2,fich:2,servic:2,cpu:2,environn:1}}) \ No newline at end of file +Search.setIndex({objects:{},terms:{"2iop":2,code:[],check_merethis_vmware_datastorio:2,trl_lun2:2,librairi:2,global:2,all:1,yellow:2,"nomm\u00e9":[],"\u00e9clat\u00e9":[],fourni:[],row:[],indicateur:2,depend:1,"27iop":2,send:[1,2],init:1,program:2,"surallou\u00e9":2,aux:2,sent:2,valeur:2,"d\u00e9j\u00e0":2,sond:2,"valid\u00e9":[],"22743040o":2,util:2,hardwar:1,sont:2,garder:[],check_merethis_vmware_nethost:2,vmtool:2,level:1,necessit:2,list:[0,2],"d\u00e9marrag":[],servic:2,x86_64:1,visualis:2,"362747904o":2,"derni\u00e8r":[],direct:2,syslog:[1,2],second:2,pass:2,download:1,port:2,vmware:[1,2],supervis:[],"_hostvcnam":2,section:[],quelqu:2,statushost:2,riops_lun1:2,communiqu:2,version:1,sur:2,peuvent:2,net:1,cela:[],"charg\u00e9":[],full:1,"contr\u00f4ler":2,voici:[],snapshost:2,bodi:[],solari:[],"fonctionnalit\u00e9":[],modifi:2,valu:2,"m\u00eame":[],"tr\u00e8":[],search:[0,1],"v\u00e9rific":[],"r\u00e9cup\u00e8r":[],beaucoup:[],"g\u00e9n\u00e9riqu":2,datetim:1,action:2,que:2,environn:[],"risqu\u00e9":[],modul:[0,1,2],souhaitez:2,ask:2,unix:[1,2],instal:[0,1,2],total:2,"1773761536o":2,commun:2,lwp:1,upgrad:1,perl:[1,2],connector:1,latenc:2,overhead:2,rhel:[0,1],scope:1,vcenter:2,addtionn:1,type:2,swap:2,ensuit:2,riop:2,check_merethis_vmware_cpuhost:2,log_daemon:2,filtrer:2,check_merethis_vmware_datastoresvm:2,iso8601:1,warn:2,twl_lun2:2,twl_lun1:2,moin:2,recommand:1,cach:2,"rattach\u00e9":2,must:1,augment:[],car:2,work:2,uniqu:2,pour:2,minimum:[],client:2,taux:2,nagio:1,root:1,"506574405632o":2,tar:1,process:2,requi:[],share:[1,2],check_merethis_vmware_swaphost:2,templat:2,critic:2,unzip:1,check_merethis_vmware_healthhost:2,"r\u00e9pons":[],traffic_out:2,suivant:2,gcc:1,refresh_keeper_sess:2,"totalit\u00e9":2,rapport:2,write:[],toolsnotinstal:2,optimal:2,memoir:2,updat:1,xxxx:2,"r\u00e9sultat":2,swap_in:2,mac:2,attent:[],mai:[1,2],datastoresvm:2,datastor:2,data:[1,2],"remont\u00e9":2,souci:[],welcom:0,permet:2,light:2,timeout_kil:2,correspond:[1,2],allon:[],issu:2,inform:2,ensembl:2,order:2,"m\u00e9moir":2,"d\u00e9faut":2,offici:[],peut:2,increas:1,"00mhz":2,afin:2,"h\u00e9bergeant":2,kbp:2,jnh:1,"r\u00e9colter":2,reseau:2,"_servicethreshold":2,uuid:1,window:[],"\u00e9critur":2,memhost:2,nom:2,non:[],"syst\u00e8m":2,handl:2,qualiti:2,dan:[0,2],taill:2,devel:1,"\u00e9galement":2,effectu:2,autr:[],optionnel:2,nou:[],son:[],"1jour":2,check_merethis_vmware_snapshotvm:2,critiqu:2,name:[1,2],aucun:2,troubleshoot:2,"g\u00e9n\u00e9raux":[],temps_cour:2,"install\u00e9":[],check_merethis_vmware_datastoreusag:2,mode:2,timeout:2,done:1,cett:2,espac:2,ouvr:2,"cr\u00e9er":2,connect:2,"r\u00e9seau":2,distrib:1,our:2,"probl\u00e8m":2,variabl:2,respectiv:[],mettr:[],reboot:1,content:0,"\u00e9cout":2,health:2,traffic_in:2,centreon_esxd:[1,2],red:2,serveur:2,"contr\u00f4l":[0,2],check_merethis_vmware_maintenancehost:2,e2fsprog:1,hazard:1,qui:2,org:1,selon:2,contient:2,libuuid:1,openssl:1,keep:2,filter:2,liaison:2,yum:1,isn:2,outsid:1,unknown:2,principl:2,poller:1,processeur:2,oper:[1,2],softwar:1,"pr\u00e9sent\u00e9":[],check_merethis_vmware_countvmhost:2,mise:[],"pr\u00e9":[],number:1,votr:[],affich:2,donc:[],"indiqu\u00e9":2,crit:2,virtualcent:2,tou:2,open:2,ont:2,size:2,fonctionn:2,start:[1,2],"_hostesxdport":2,mkdir:1,system:[0,1],least:2,trl_lun1:2,nethost:2,"final":2,shell:[],option:2,"poss\u00e8d":2,cpu2:2,cpu3:2,specifi:2,cpu1:2,"d\u00e9pend":2,date:[1,2],virtuel:2,centreon_esx_cli:[1,2],ssl3_get_record:2,provid:2,"00iop":2,older:2,wiops_lun2:2,wiops_lun1:2,timeout_vspher:2,ressourc:[1,2],sera:2,"red\u00e9marr":[],cpu_total_mhz:2,"acc\u00e8":2,ram:1,aussi:2,myvmnam:2,titl:[],"56196403200o":2,wiop:2,tabl:0,need:1,requisit:[],optimis:[0,2],troi:2,jour:[],lib:[1,2],min:2,check:[1,2],hostvcnam:2,"d\u00e9connexion":2,libpath:2,exampl:2,fonction:[],deux:[],soap:[1,2],simplifi:2,begin:1,macro:2,"sp\u00e9cifier":2,swaphost:2,usernam:2,"configur\u00e9":2,who:1,plat:2,doit:2,dessu:2,maintenancehost:2,cpu0:2,"v\u00e9rifier":[],toolsnotrun:2,"class":1,charg:2,countvm:2,url:2,request:2,snapshot:[1,2],"_servicedsnam":2,"68705865728o":2,"\u00e9tat":2,vcname:2,"n\u00e9cessair":2,"cr\u00e9\u00e9":[],text:[],subprocess:2,directli:2,session:2,threshold:2,identifi:2,trop:2,retrouv:2,xml:1,fichier:2,onli:2,menu:2,configur:[0,1,2],activ:2,"cr\u00e9ant":[],"cr\u00e9ation":2,"70148096o":2,"diff\u00e9rent":2,"s\u00e9par\u00e9":2,yml:[],count:2,get:2,centron:2,cpuvm:2,ssl:2,mainten:[1,2],"pr\u00eat":[],"t\u00e9l\u00e9chargement":[],champ:2,vsphere_serv:2,esxd:[0,1,2],"172032b":2,"2147483648o":2,requir:1,snapshotvm:2,grai:2,bad:2,write_r:2,"\u00e9vite":2,"caract\u00e8r":2,swap_out:2,riops_lun2:2,"643976658944o":2,"_servicecrit":2,"recommand\u00e9":2,respons:2,fail:2,sen:2,xxxxx:2,sorti:2,centreon:[0,1,2],nombr:2,vari:1,vont:2,"_servicewarn":2,gener:2,attribut:2,parent:2,check_merethis_vmware_memhost:2,pourcentag:2,comm:2,avon:[],cli:1,last:1,plugin:[1,2],"sp\u00e9cifi\u00e9":2,etc:[1,2],monitor:[1,2],erreur:2,rend:[],improv:1,login:2,com:[],pre:[],"d\u00e9conseill\u00e9":2,makefil:1,"d\u00e9finit":2,perfdata:2,exploit:[0,2],"d\u00e9finir":2,linux:1,connexion:[],aller:2,been:1,json:[],wait:2,"pr\u00e9sent":2,difficil:[],datastoreshost:2,cpu_tot:2,xxx:2,"identit\u00e9":2,demand:[],viperltoolkit:[],toolsvm:2,present:[0,2],correpond:1,"entr\u00e9":2,"ais\u00e9":[],"_hostesxdhost":2,error:2,"1408f119":2,stdout:2,envoy:[],expat:1,"4561920o":2,"allum\u00e9":2,"00m":2,vou:2,libxml:1,archiv:1,cento:[0,1],conf:1,chkconfig:1,situ:2,par:2,develop:[],log_crit:2,minim:1,perform:2,make:[1,2],memvm:2,same:1,"pr\u00e9senc":2,fragment:2,"ex\u00e9cut":2,"imp\u00e9rativ":[],traiter:2,grand:2,lite:1,document:[0,1,2],complet:1,http:[1,2],statut:2,nic:2,"d\u00e9fini":2,nicnam:2,vieux:2,moyen:2,center:2,"h\u00f4te":2,"allou\u00e9":2,notr:[],"r\u00e9cup\u00e9rer":[],traffic_:2,without:1,command:2,thi:[1,2],choos:1,san:2,programm:[],"g\u00e9n\u00e8re":2,protocol:[1,2],physiqu:2,tcp:2,indic:[0,2],processu:[],ayant:[],connecteur:2,bit:[],"renvoy\u00e9":2,site:[],virgul:2,toolsold:2,exempl:2,"cibl\u00e9":2,bloc:[],log_facil:2,enfin:[],"bas\u00e9":2,adress:2,esxdhost:2,bin:1,advis:1,format:1,read:2,mot:2,cpan:[1,2],remont:2,check_merethis_vmware_datastoreshost:2,healthhost:2,password:2,daemon:[1,2],header:[],fournir:2,officiel:[],dsname:2,noth:2,collect:[],princip:[],index:0,"pr\u00e9alabl":2,page:0,"r\u00f4le":[],vsphere:[1,2],besoin:2,swap_:2,interv:2,seuil:2,some:1,back:2,"14344192b":2,log_mod:2,hostesxdhost:2,bloqu:2,server:[1,2],"n\u00e9cessit":[],ouvert:[],tmp:2,est:2,"mat\u00e9riel":2,octet:2,per:2,esx:2,retri:2,xxxxxx:2,avoir:2,minimal:[],machin:2,plu:2,sensibl:[],ancien:2,usag:2,host:[1,2],prerequisit:[0,1],"test\u00e9":[],wget:1,"\u00eatre":2,column:[],slightli:1,commit:1,"donn\u00e9":[],zxvf:1,routin:2,read_rat:2,additionn:1,www:[],two:2,lier:2,"archiv\u00e9":[],sou:[],retourn:2,lieu:2,ensur:2,mymeta:[],your:1,websit:1,testvc:2,log:2,plusieur:[],support:[],logiciel:[],lor:2,esx1:2,interfac:2,author:1,lot:1,comport:2,"1589248b":2,methodmak:1,usr:[1,2],lun2:2,lun1:2,pleinement:2,form:2,link:[],cpuhost:2,sdk:[1,2],info:2,vive:[],temp:2,possibl:[1,2],"default":2,avec:2,record:2,"cha\u00een":2,notam:2,step:2,fich:2,more:[1,2],vmnic0:2,featur:1,"s\u00e9rie":2,creat:2,user1:2,certain:[],utilis:2,decrypt:2,lectur:2,"m\u00e9triqu":2,file:[1,2],dessou:2,"mod\u00e8l":2,hostesxdport:2,commenc:[],"occup\u00e9":2,courant:2,check_merethis_vmware_statushost:2,crypt:1,seul:2,boot:1,virtual:[1,2],other:1,"_servicenicnam":2,normal:2,viell:2,test:[1,2],snaphost:2,architectur:[1,2],countvmhost:2,check_merethis_vmware_toolsvm:2,cpu0_mhz:2,hostaddress:2,"param\u00e8tr":2,check_merethis_vmware_cpuvm:2,balloon:2,lanc:[],niveau:2,exclu:[],ssleai:1,descript:2,check_merethis_vmware_memvm:2,"598016b":2,esxdport:2,"t\u00e9l\u00e9charger":[],cpu:[1,2]},objtypes:{},titles:["Welcome to Centreon ESXD’s documentation!","Installation","Exploitation"],objnames:{},filenames:["index","installation/index","exploitation/index"]}) \ No newline at end of file diff --git a/connectors/vmware/doc-en/exploitation/index.rst b/connectors/vmware/doc-en/exploitation/index.rst index ea9bede9a..34cbfba2f 100644 --- a/connectors/vmware/doc-en/exploitation/index.rst +++ b/connectors/vmware/doc-en/exploitation/index.rst @@ -5,38 +5,38 @@ Exploitation Centreon-esxd Presentation --------------------------- -Principes Généraux -`````````````````` +Generals Principles +``````````````````` -Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. +Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter. -Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : +By default "centreon-esxd" starts at least two processes (named "handle-client" and "handle-vsphere-xxxx") : *« handle-client »*: - *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + *Process waiting for requests of "centron-esx-client.pl" clients.* -Voici le fonctionnement : +Steps of operation : -- Un client se connecte. -- Le client demande un indicateur de supervision sur un VirtualCenter. -- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». -- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». -- Le processus « handle-client » fourni la réponse au client. +- A client connects. +- The client ask an monitoring indicator on a VirtualCenter. +- The process "handle-client" sends the request to process "handle-vsphere-xxxx". +- A response is sent by "handle-vsphere-xxxx" to "handle-client". +- The process "handle-client" sends the response to the client. *« handle-vsphere-xxxx »*: - *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* + *Process responsible to connect and to keep opened a session with the VirtualCenter. To ensure quality performance, a cache of datas description is created.* -Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. +Then, this process gets back the VMWare indicators creating a subprocess per request. -Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. +Centreon-esxd necessitates the utilization of one (or more) VirtualCenter. It isn't possible to get back informations of an ESX server directly. -Voici un exemple d'architecture éclaté : +This is a example of a fragmented architecture : .. image:: ../images/archi.png -Mode de fonctionnement -`````````````````````` -Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). +Operating mode +`````````````` +The "centreon-esxd" program only works in "daemon" mode. (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. diff --git a/connectors/vmware/doc-en/images/archi.png b/connectors/vmware/doc-en/images/archi.png index 82dca91fec4159d8be96155e65412aa0fd645059..f83c5281e36dac30d5c47b4ad131dd03a9807390 100644 GIT binary patch literal 25993 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 Oih_))G)&4g=>GsL(zAX5 literal 29775 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 diff --git a/connectors/vmware/doc-en/installation/index.rst b/connectors/vmware/doc-en/installation/index.rst index 03e2ed3f4..fd8b2f207 100644 --- a/connectors/vmware/doc-en/installation/index.rst +++ b/connectors/vmware/doc-en/installation/index.rst @@ -3,7 +3,7 @@ Installation ============ Prerequisites -========== +============= Software Recommandations ```````````````````````` @@ -34,10 +34,10 @@ Centreon-esxd Installation - centos/rhel 5 systems SDK Perl VMWare Installation ```````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. +The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. -Installer les pré-requis CPAN:: +Install CPAN prerequisites :: root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel root # yum install perl-XML-LibXML perl-Crypt-SSLeay @@ -112,9 +112,9 @@ Centreon-esxd Installation - centos/rhel 6 systems SDK Perl VMWare Installation ````````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. +The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. -Installer les pré-requis CPAN:: +Install CPAN prerequisites :: root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite From 83880bce85a72d4a0220e81f4b874d6991e21647 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 28 Jun 2013 16:04:49 +0000 Subject: [PATCH 039/447] 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; From 0290faf5014636f7d3c3b02ea1e1de5612dde283 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 2 Jul 2013 07:34:22 +0000 Subject: [PATCH 040/447] Ref #4870 #5490 #5495 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@58 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 810 +++++++++--------- connectors/vmware/centreonesxd.pm | 395 +++++---- connectors/vmware/lib/cmdcountvmhost.pm | 99 +++ connectors/vmware/lib/cmdcpuhost.pm | 104 +++ connectors/vmware/lib/cmdcpuvm.pm | 105 +++ connectors/vmware/lib/cmddatastoreio.pm | 97 +++ connectors/vmware/lib/cmddatastoreshost.pm | 159 ++++ connectors/vmware/lib/cmddatastoresvm.pm | 160 ++++ connectors/vmware/lib/cmddatastoreusage.pm | 90 ++ connectors/vmware/lib/cmdgetmap.pm | 77 ++ connectors/vmware/lib/cmdhealthhost.pm | 122 +++ connectors/vmware/lib/cmdlistdatastore.pm | 57 ++ connectors/vmware/lib/cmdlisthost.pm | 54 ++ connectors/vmware/lib/cmdlistnichost.pm | 68 ++ connectors/vmware/lib/cmdmaintenancehost.pm | 65 ++ connectors/vmware/lib/cmdmemhost.pm | 96 +++ connectors/vmware/lib/cmdmemvm.pm | 102 +++ connectors/vmware/lib/cmdnethost.pm | 112 +++ connectors/vmware/lib/cmdsnapshotvm.pm | 106 +++ connectors/vmware/lib/cmdstatushost.pm | 81 ++ connectors/vmware/lib/cmdswaphost.pm | 94 ++ connectors/vmware/lib/cmdswapvm.pm | 94 ++ connectors/vmware/lib/cmdtoolsvm.pm | 70 ++ connectors/vmware/lib/cmduptimehost.pm | 73 ++ connectors/vmware/lib/command-countvmhost.pm | 74 -- connectors/vmware/lib/command-cpuhost.pm | 77 -- connectors/vmware/lib/command-cpuvm.pm | 79 -- connectors/vmware/lib/command-datastoreio.pm | 68 -- .../vmware/lib/command-datastoreshost.pm | 132 --- connectors/vmware/lib/command-datastoresvm.pm | 133 --- .../vmware/lib/command-datastoreusage.pm | 64 -- connectors/vmware/lib/command-getmap.pm | 53 -- connectors/vmware/lib/command-healthhost.pm | 97 --- .../vmware/lib/command-listdatastore.pm | 32 - connectors/vmware/lib/command-listhost.pm | 30 - connectors/vmware/lib/command-listnichost.pm | 43 - .../vmware/lib/command-maintenancehost.pm | 39 - connectors/vmware/lib/command-memhost.pm | 70 -- connectors/vmware/lib/command-memvm.pm | 75 -- connectors/vmware/lib/command-nethost.pm | 86 -- connectors/vmware/lib/command-snapshotvm.pm | 83 -- connectors/vmware/lib/command-statushost.pm | 57 -- connectors/vmware/lib/command-swaphost.pm | 67 -- connectors/vmware/lib/command-swapvm.pm | 67 -- connectors/vmware/lib/command-toolsvm.pm | 46 - connectors/vmware/lib/command-uptimehost.pm | 43 - connectors/vmware/lib/common.pm | 342 ++++---- 47 files changed, 2878 insertions(+), 2269 deletions(-) create mode 100644 connectors/vmware/lib/cmdcountvmhost.pm create mode 100644 connectors/vmware/lib/cmdcpuhost.pm create mode 100644 connectors/vmware/lib/cmdcpuvm.pm create mode 100644 connectors/vmware/lib/cmddatastoreio.pm create mode 100644 connectors/vmware/lib/cmddatastoreshost.pm create mode 100644 connectors/vmware/lib/cmddatastoresvm.pm create mode 100644 connectors/vmware/lib/cmddatastoreusage.pm create mode 100644 connectors/vmware/lib/cmdgetmap.pm create mode 100644 connectors/vmware/lib/cmdhealthhost.pm create mode 100644 connectors/vmware/lib/cmdlistdatastore.pm create mode 100644 connectors/vmware/lib/cmdlisthost.pm create mode 100644 connectors/vmware/lib/cmdlistnichost.pm create mode 100644 connectors/vmware/lib/cmdmaintenancehost.pm create mode 100644 connectors/vmware/lib/cmdmemhost.pm create mode 100644 connectors/vmware/lib/cmdmemvm.pm create mode 100644 connectors/vmware/lib/cmdnethost.pm create mode 100644 connectors/vmware/lib/cmdsnapshotvm.pm create mode 100644 connectors/vmware/lib/cmdstatushost.pm create mode 100644 connectors/vmware/lib/cmdswaphost.pm create mode 100644 connectors/vmware/lib/cmdswapvm.pm create mode 100644 connectors/vmware/lib/cmdtoolsvm.pm create mode 100644 connectors/vmware/lib/cmduptimehost.pm delete mode 100644 connectors/vmware/lib/command-countvmhost.pm delete mode 100644 connectors/vmware/lib/command-cpuhost.pm delete mode 100644 connectors/vmware/lib/command-cpuvm.pm delete mode 100644 connectors/vmware/lib/command-datastoreio.pm delete mode 100644 connectors/vmware/lib/command-datastoreshost.pm delete mode 100644 connectors/vmware/lib/command-datastoresvm.pm delete mode 100644 connectors/vmware/lib/command-datastoreusage.pm delete mode 100644 connectors/vmware/lib/command-getmap.pm delete mode 100644 connectors/vmware/lib/command-healthhost.pm delete mode 100644 connectors/vmware/lib/command-listdatastore.pm delete mode 100644 connectors/vmware/lib/command-listhost.pm delete mode 100644 connectors/vmware/lib/command-listnichost.pm delete mode 100644 connectors/vmware/lib/command-maintenancehost.pm delete mode 100644 connectors/vmware/lib/command-memhost.pm delete mode 100644 connectors/vmware/lib/command-memvm.pm delete mode 100644 connectors/vmware/lib/command-nethost.pm delete mode 100644 connectors/vmware/lib/command-snapshotvm.pm delete mode 100644 connectors/vmware/lib/command-statushost.pm delete mode 100644 connectors/vmware/lib/command-swaphost.pm delete mode 100644 connectors/vmware/lib/command-swapvm.pm delete mode 100644 connectors/vmware/lib/command-toolsvm.pm delete mode 100644 connectors/vmware/lib/command-uptimehost.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 952e06d0a..1a3179636 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -7,7 +7,7 @@ use Getopt::Long; my $PROGNAME = $0; my $VERSION = "1.3"; -my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); +my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3, 'DEPENDENT' => 4); my $socket; sub print_help(); @@ -15,52 +15,52 @@ sub print_usage(); sub print_revision($$); my %OPTION = ( - "help" => undef, "version" => undef, - "esxd-host" => undef, "esxd-port" => 5700, - "vsphere" => '', - "usage" => undef, - "light-perfdata" => undef, - "esx-host" => undef, - "datastore" => undef, - "nic" => undef, - "warning" => undef, - "critical" => undef + "help" => undef, "version" => undef, + "esxd-host" => undef, "esxd-port" => 5700, + "vsphere" => '', + "usage" => undef, + "light-perfdata" => undef, + "esx-host" => undef, + "datastore" => undef, + "nic" => undef, + "warning" => undef, + "critical" => undef ); Getopt::Long::Configure('bundling'); GetOptions( - "h|help" => \$OPTION{'help'}, - "V|version" => \$OPTION{'version'}, - "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, - "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, + "h|help" => \$OPTION{'help'}, + "V|version" => \$OPTION{'version'}, + "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, + "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, - "vsphere=s" => \$OPTION{'vsphere'}, + "vsphere=s" => \$OPTION{'vsphere'}, - "u|usage=s" => \$OPTION{'usage'}, - "e|esx-host=s" => \$OPTION{'esx-host'}, - "vm=s" => \$OPTION{'vm'}, - - "filter-datastores=s" => \$OPTION{'filter-datastores'}, - "light-perfdata" => \$OPTION{'light-perfdata'}, - "datastore=s" => \$OPTION{'datastore'}, - "nic=s" => \$OPTION{'nic'}, + "u|usage=s" => \$OPTION{'usage'}, + "e|esx-host=s" => \$OPTION{'esx-host'}, + "vm=s" => \$OPTION{'vm'}, + + "filter-datastores=s" => \$OPTION{'filter-datastores'}, + "light-perfdata" => \$OPTION{'light-perfdata'}, + "datastore=s" => \$OPTION{'datastore'}, + "nic=s" => \$OPTION{'nic'}, - "older=i" => \$OPTION{'older'}, - "warn" => \$OPTION{'warn'}, - "crit" => \$OPTION{'crit'}, + "older=i" => \$OPTION{'older'}, + "warn" => \$OPTION{'warn'}, + "crit" => \$OPTION{'crit'}, - "w|warning=i" => \$OPTION{'warning'}, - "c|critical=i" => \$OPTION{'critical'}, + "w|warning=i" => \$OPTION{'warning'}, + "c|critical=i" => \$OPTION{'critical'}, ); if (defined($OPTION{'version'})) { - print_revision($PROGNAME, $VERSION); - exit $ERRORS{'OK'}; + print_revision($PROGNAME, $VERSION); + exit $ERRORS{'OK'}; } if (defined($OPTION{'help'})) { - print_help(); - exit $ERRORS{'OK'}; + print_help(); + exit $ERRORS{'OK'}; } ############# @@ -68,124 +68,124 @@ if (defined($OPTION{'help'})) { ############# sub print_usage () { - print "Usage: "; - print $PROGNAME."\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; - print " -H centreon-esxd Host (required)\n"; - print " -P centreon-esxd Port (default 5700)\n"; - print " --vsphere vsphere name (default: none)\n"; - print " -u (--usage) What to check. The list and args (required)\n"; - print "\n"; - print "'healthhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'maintenancehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'statushost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'datastore-usage':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'datastore-io':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in kBps (default none)\n"; - print " -c (--critical) Critical Threshold in kBps (default none)\n"; - print "\n"; - print "'cpuhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print " --light-perfdata Display only total average cpu perfdata\n"; - print "\n"; - print "'nethost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --nic Physical nic name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'memhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'swaphost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; - print "'datastoreshost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; - print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; - print " --filter-datastores Datastores to verify (separated by coma)\n"; - print "\n"; - print "'countvmhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold (default none)\n"; - print " -c (--critical) Critical Threshold (default none)\n"; - print "\n"; - print "'uptimehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'cpuvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'toolsvm':\n"; - print " --vm VM to check (required)\n"; - print "\n"; - print "'snapshotvm':\n"; - print " --vm VM to check (required)\n"; - print " --older If older than ms\n"; - print " --crit Critical if: there is a snasphot, or a snapshot is older than (--older)\n"; - print " --warn Warn if: there is a snasphot, or a snapshot is older than (--older)\n"; - print "\n"; - print "'datastoresvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in IOPS (default none)\n"; - print " -c (--critical) Critical Threshold in IOPS (default none)\n"; - print "\n"; - print "'memvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'swapvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; - print "'listhost':\n"; - print " None\n"; - print "\n"; - print "'listdatastore':\n"; - print " None\n"; - print "\n"; - print "'listnichost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'getmap':\n"; - print " -e (--esx-host) Esx Host to check\n"; - print "\n"; - print "'stats':\n"; - print " -w (--warning) Warning Threshold in total client connections (default none)\n"; - print " -c (--critical) Critical Threshold in total client connections (default none)\n"; + print "Usage: "; + print $PROGNAME."\n"; + print " -V (--version) Plugin version\n"; + print " -h (--help) usage help\n"; + print " -H centreon-esxd Host (required)\n"; + print " -P centreon-esxd Port (default 5700)\n"; + print " --vsphere vsphere name (default: none)\n"; + print " -u (--usage) What to check. The list and args (required)\n"; + print "\n"; + print "'healthhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'maintenancehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'statushost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'datastore-usage':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'datastore-io':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in kBps (default none)\n"; + print " -c (--critical) Critical Threshold in kBps (default none)\n"; + print "\n"; + print "'cpuhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " --light-perfdata Display only total average cpu perfdata\n"; + print "\n"; + print "'nethost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " --nic Physical nic name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'memhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'swaphost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; + print "'datastoreshost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; + print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; + print " --filter-datastores Datastores to verify (separated by coma)\n"; + print "\n"; + print "'countvmhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold (default none)\n"; + print " -c (--critical) Critical Threshold (default none)\n"; + print "\n"; + print "'uptimehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'cpuvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'toolsvm':\n"; + print " --vm VM to check (required)\n"; + print "\n"; + print "'snapshotvm':\n"; + print " --vm VM to check (required)\n"; + print " --older If older than ms\n"; + print " --crit Critical if: there is a snasphot, or a snapshot is older than (--older)\n"; + print " --warn Warn if: there is a snasphot, or a snapshot is older than (--older)\n"; + print "\n"; + print "'datastoresvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in IOPS (default none)\n"; + print " -c (--critical) Critical Threshold in IOPS (default none)\n"; + print "\n"; + print "'memvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'swapvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; + print "'listhost':\n"; + print " None\n"; + print "\n"; + print "'listdatastore':\n"; + print " None\n"; + print "\n"; + print "'listnichost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'getmap':\n"; + print " -e (--esx-host) Esx Host to check\n"; + print "\n"; + print "'stats':\n"; + print " -w (--warning) Warning Threshold in total client connections (default none)\n"; + print " -c (--critical) Critical Threshold in total client connections (default none)\n"; } sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2005-2012 Centreon #\n"; - print "# Bugs to http://redmine.merethis.net/ #\n"; - print "##############################################\n"; - print "\n"; - print_usage(); - print "\n"; + print "##############################################\n"; + print "# Copyright (c) 2005-2012 Centreon #\n"; + print "# Bugs to http://redmine.merethis.net/ #\n"; + print "##############################################\n"; + print "\n"; + print_usage(); + print "\n"; } sub print_revision($$) { @@ -195,13 +195,13 @@ sub print_revision($$) { } sub myconnect { - if (!($socket = IO::Socket::INET->new( Proto => "tcp", - PeerAddr => $OPTION{'esxd-host'}, - PeerPort => $OPTION{'esxd-port'}))) { - print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; - exit $ERRORS{'UNKNOWN'}; - } - $socket->autoflush(1); + if (!($socket = IO::Socket::INET->new( Proto => "tcp", + PeerAddr => $OPTION{'esxd-host'}, + PeerPort => $OPTION{'esxd-port'}))) { + print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; + exit $ERRORS{'UNKNOWN'}; + } + $socket->autoflush(1); } ################# @@ -209,120 +209,120 @@ sub myconnect { ################# sub maintenancehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; } sub maintenancehost_get_str { - return "maintenancehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return "maintenancehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub statushost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; } sub statushost_get_str { - return "statushost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return "statushost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub healthhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; } sub healthhost_get_str { - return "healthhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return "healthhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub datastoreusage_check_arg { - if (!defined($OPTION{'datastore'})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; } sub datastoreusage_get_str { - return "datastoreusage|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastore-usage|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub datastoreio_check_arg { - if (!defined($OPTION{'datastore'})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; - } - return 0; + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + return 0; } sub datastoreio_get_str { - return "datastoreio|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastore-io|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub cpuhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - if (!defined($OPTION{'light-perfdata'})) { - $OPTION{'light-perfdata'} = 0; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + if (!defined($OPTION{'light-perfdata'})) { + $OPTION{'light-perfdata'} = 0; + } + return 0; } sub cpuhost_get_str { - return "cpuhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'light-perfdata'}; + return "cpuhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'light-perfdata'}; } sub datastoreshost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; - } - if (!defined($OPTION{'filter-datastores'})) { - $OPTION{'filter-datastores'} = ''; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + if (!defined($OPTION{'filter-datastores'})) { + $OPTION{'filter-datastores'} = ''; + } + return 0; } sub datastoreshost_get_str { @@ -330,155 +330,155 @@ sub datastoreshost_get_str { } sub memhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; } sub memhost_get_str { - return "memhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "memhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub swaphost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 0.8; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 1; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 0.8; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 1; + } + return 0; } sub swaphost_get_str { - return "swaphost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "swaphost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub nethost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'nic'})) { - print "Option --nic is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'nic'})) { + print "Option --nic is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; } sub nethost_get_str { - return "nethost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "nethost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub countvmhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + return 0; } sub countvmhost_get_str { - return "countvmhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "countvmhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub uptimehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; } sub uptimehost_get_str { - return "uptimehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return "uptimehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub cpuvm_check_arg { - if (!defined($OPTION{'vm'})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; } sub cpuvm_get_str { - return "cpuvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "cpuvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub toolsvm_check_arg { - if (!defined($OPTION{'vm'})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; } sub toolsvm_get_str { - return "toolsvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'}; + return "toolsvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'}; } sub snapshotvm_check_arg { - if (!defined($OPTION{'vm'})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'older'})) { - $OPTION{'older'} = ''; - } - if (!defined($OPTION{'warn'})) { - $OPTION{'warn'} = 0; - } else { - $OPTION{'warn'} = 1; - } - if (!defined($OPTION{'crit'})) { - $OPTION{'crit'} = 0; - } else { - $OPTION{'crit'} = 1; - } - return 0; + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'older'})) { + $OPTION{'older'} = ''; + } + if (!defined($OPTION{'warn'})) { + $OPTION{'warn'} = 0; + } else { + $OPTION{'warn'} = 1; + } + if (!defined($OPTION{'crit'})) { + $OPTION{'crit'} = 0; + } else { + $OPTION{'crit'} = 1; + } + return 0; } sub snapshotvm_get_str { - return "snapshotvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; + return "snapshotvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; } sub datastoresvm_check_arg { @@ -487,130 +487,130 @@ sub datastoresvm_check_arg { print_usage(); exit $ERRORS{'UNKNOWN'}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; - } - return 0; + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + return 0; } sub datastoresvm_get_str { - return "datastoresvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "datastoresvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub memvm_check_arg { - if (!defined($OPTION{'vm'})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; - } - return 0; + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 80; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 90; + } + return 0; } sub memvm_get_str { - return "memvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "memvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub swapvm_check_arg { - if (!defined($OPTION{'vm'})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 0.8; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 1; - } - return 0; + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = 0.8; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = 1; + } + return 0; } sub swapvm_get_str { - return "swapvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "swapvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } sub listhost_check_arg { - return 0; + return 0; } sub listhost_get_str { - return "listhost|" . $OPTION{'vsphere'}; + return "listhost|" . $OPTION{'vsphere'}; } sub listdatastore_check_arg { - return 0; + return 0; } sub listdatastore_get_str { - return "listdatastore|" . $OPTION{'vsphere'}; + return "listdatastore|" . $OPTION{'vsphere'}; } sub listnichost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + return 0; } sub listnichost_get_str { - return "listnichost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return "listnichost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub getmap_check_arg { - if (!defined($OPTION{'esx-host'})) { - $OPTION{'esx-host'} = ""; - } - return 0; + if (!defined($OPTION{'esx-host'})) { + $OPTION{'esx-host'} = ""; + } + return 0; } sub getmap_get_str { - return "getmap|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return "getmap|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; } sub stats_check_arg { - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ""; - } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ""; - } - return 0; + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ""; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ""; + } + return 0; } sub stats_get_str { - return "stats||" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return "stats||" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } ################# ################# if (!defined($OPTION{'esxd-host'})) { - print "Option -H (--esxd-host) is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; + print "Option -H (--esxd-host) is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; } if (!defined($OPTION{'usage'})) { - print "Option -u (--usage) is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; + print "Option -u (--usage) is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; } if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|listhost|listdatastore|listnichost|getmap|stats)$/) { - print "Usage value is unknown\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; + print "Usage value is unknown\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; } $OPTION{'usage'} =~ s/-//g; @@ -630,7 +630,7 @@ $return =~ s/^(-?[0-9]*?)\|//; print $return . "\n"; if ($status_return == -1) { - $status_return = 3; + $status_return = 3; } exit $status_return; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 021abf2da..0eeecee2c 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -14,13 +14,36 @@ use centreon::script; use centreon::esxd::common; BEGIN { - $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; + $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; } use base qw(centreon::script); use vars qw(%centreonesxd_config); my %handlers = ('TERM' => {}, 'HUP' => {}, 'CHLD' => {}); +my @load_modules = ('centreon::esxd::cmdcountvmhost', + 'centreon::esxd::cmdcpuhost', + 'centreon::esxd::cmdcpuvm', + 'centreon::esxd::cmddatastoreio', + 'centreon::esxd::cmddatastoreshost', + 'centreon::esxd::cmddatastoresvm', + 'centreon::esxd::cmddatastoreusage', + 'centreon::esxd::cmdgetmap', + 'centreon::esxd::cmdhealthhost', + 'centreon::esxd::cmdlistdatastore', + 'centreon::esxd::cmdlisthost', + 'centreon::esxd::cmdlistnichost', + 'centreon::esxd::cmdmemhost', + 'centreon::esxd::cmdmaintenancehost', + 'centreon::esxd::cmdmemvm', + 'centreon::esxd::cmdnethost', + 'centreon::esxd::cmdsnapshotvm', + 'centreon::esxd::cmdstatushost', + 'centreon::esxd::cmdswaphost', + 'centreon::esxd::cmdswapvm', + 'centreon::esxd::cmdtoolsvm', + 'centreon::esxd::cmduptimehost' + ); sub new { my $class = shift; @@ -77,6 +100,7 @@ sub new { $self->{whoaim} = undef; # to know which vsphere to connect $self->{filenos} = {}; $self->{module_date_parse_loaded} = 0; + $self->{modules_registry} = {}; return $self; } @@ -99,6 +123,9 @@ sub init { $self->{centreonesxd_config} = {%{$self->{centreonesxd_default_config}}, %centreonesxd_config}; + ##### Load modules + $self->load_module(@load_modules); + ##### credstore check ##### if (defined($self->{credstore_use}) && defined($self->{credstore_file}) && $self->{credstore_use} == 1 && -e "$self->{credstore_file}") { @@ -127,10 +154,10 @@ sub init { } } - eval 'require DateTime::Format::ISO8601'; + eval 'require Date::Parse'; if (!$@) { $self->{module_date_parse_loaded} = 1; - require DateTime::Format::ISO8601; + require Date::Parse; } $self->set_signal_handlers; @@ -166,9 +193,9 @@ sub class_handle_CHLD { } sub handle_TERM { - my $self = shift; + my $self = shift; $self->{logger}->writeLogInfo("$$ Receiving order to stop..."); - $self->{stop} = 1; + $self->{stop} = 1; } sub handle_HUP { @@ -179,200 +206,212 @@ sub handle_HUP { sub handle_CHLD { my $self = shift; - my $child_pid; + my $child_pid; - while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { - $self->{return_child}{$child_pid} = {'status' => 1, 'rtime' => time()}; - } - $SIG{CHLD} = \&class_handle_CHLD; + 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]; + print $self->{global_id} . "|" . $_[0]; +} + +sub load_module { + my $self = shift; + + for (@_) { + (my $file = "$_.pm") =~ s{::}{/}g; + require $file; + my $obj = $_->new($self->{logger}, $self); + $self->{modules_registry}->{$obj->getCommandName()} = $obj; + } } sub verify_child { my $self = shift; - my $progress = 0; - my $handle_writer_pipe = ${$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_one'}}; + 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}->{$_}; - } - } + # 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; + return $progress; } sub vsphere_handler { my $self = shift; - my $timeout_process; + 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(); + 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 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}, + ### + # 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"); - } - } - } + $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; + ### + # 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)); - } - } + 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 $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); + 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}; - } - } - } + $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; + $self->{modules_registry}->{$name}->initArgs(@args); + $self->{modules_registry}->{$name}->run(); + 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 { @@ -492,17 +531,17 @@ sub run { my ($name, $vsphere_name, @args) = split /\|/, $line; if ($name eq 'stats') { - centreon::esxd::common::stats_info($rh, $current_fileno, \@args); + centreon::esxd::common::stats_info($self, $rh, $current_fileno, \@args); + next; + } + if (!defined($self->{modules_registry}->{$name})) { + centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Unknown method name '$name'\n"); + next; + } + if ($self->{modules_registry}->{$name}->checkArgs(@args)) { + centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Params error '$name'\n"); 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})) { diff --git a/connectors/vmware/lib/cmdcountvmhost.pm b/connectors/vmware/lib/cmdcountvmhost.pm new file mode 100644 index 000000000..b639c2b96 --- /dev/null +++ b/connectors/vmware/lib/cmdcountvmhost.pm @@ -0,0 +1,99 @@ + +package centreon::esxd::cmdcountvmhost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'countvmhost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($lhost, $warn, $crit) = @_; + + if (!defined($lhost) || $lhost eq "") { + $self->{logger}->writeLogError("ARGS error: need host name"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : ''); + $self->{crit} = (defined($_[2]) ? $_[2] : ''); +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lhost}); + my @properties = ('vm'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @vm_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->vm) { + @vm_array = (@vm_array, @{$entity_view->vm}); + } + } + @properties = ('runtime.powerState'); + $result = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + if (!defined($result)) { + return ; + } + + my $output = ''; + my $status = 0; # OK + my $num_poweron = 0; + + foreach (@$result) { + my $power_value = lc($_->{'runtime.powerState'}->val); + if ($power_value eq 'poweredon') { + $num_poweron++; + } + } + if (defined($self->{crit}) && $self->{crit} ne "" && ($num_poweron >= $self->{crit})) { + $output = "CRITICAL: $num_poweron VM running."; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($num_poweron >= $self->{warn})) { + $output = "WARNING: $num_poweron VM running."; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } else { + $output = "OK: $num_poweron VM running."; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|count=$num_poweron\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdcpuhost.pm b/connectors/vmware/lib/cmdcpuhost.pm new file mode 100644 index 000000000..ecbcc326e --- /dev/null +++ b/connectors/vmware/lib/cmdcpuhost.pm @@ -0,0 +1,104 @@ + +package centreon::esxd::cmdcpuhost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'cpuhost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host, $warn, $crit, $light_perfdata) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 80); + $self->{crit} = (defined($_[2]) ? $_[2] : 90); + $self->{light_perfdata} = (defined($_[3]) ? $_[3] : 0); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lhost}); + my @properties = ('name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @instances = ('*'); + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'cpu.usage.average', 'instances' => \@instances}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $status = 0; # OK + my $output = ''; + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + + if ($total_cpu_average >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($total_cpu_average >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Total Average CPU usage '$total_cpu_average%' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100"; + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %$values) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "" and $self->{light_perfdata} != 1) { + $output .= " cpu$instance=" . centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; + } + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdcpuvm.pm b/connectors/vmware/lib/cmdcpuvm.pm new file mode 100644 index 000000000..16304b158 --- /dev/null +++ b/connectors/vmware/lib/cmdcpuvm.pm @@ -0,0 +1,105 @@ + +package centreon::esxd::cmdcpuvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'cpuvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm, $warn, $crit) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm hostname"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 80); + $self->{crit} = (defined($_[2]) ? $_[2] : 90); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lvm}); + my @properties = ('name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @instances = ('*'); + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'cpu.usage.average', 'instances' => \@instances}, + {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $status = 0; # OK + my $output = ''; + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + + if ($total_cpu_average >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($total_cpu_average >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %$values) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "") { + $output .= " cpu" . $instance . "_MHz=" . centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$id}[0])) . "MHz"; + } + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmddatastoreio.pm b/connectors/vmware/lib/cmddatastoreio.pm new file mode 100644 index 000000000..349d1f0c6 --- /dev/null +++ b/connectors/vmware/lib/cmddatastoreio.pm @@ -0,0 +1,97 @@ + +package centreon::esxd::cmddatastoreio; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'datastore-io'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($ds, $warn, $crit) = @_; + + if (!defined($ds) || $ds eq "") { + $self->{logger}->writeLogError("ARGS error: need datastore name"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{ds} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : ''); + $self->{crit} = (defined($_[2]) ? $_[2] : ''); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('summary.name' => $self->{ds}); + my @properties = ('summary.name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'datastore.read.average', 'instances' => ['']}, + {'label' => 'datastore.write.average', 'instances' => ['']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])); + + my $status = 0; # OK + my $output = ''; + + if ((defined($self->{warn}) && $self->{warn} ne "") && + ($read_counter >= $self->{warn} || $write_counter >= $self->{warn})) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ((defined($self->{crit}) && $self->{crit} ne "") && + ($read_counter >= $self->{crit} || $write_counter >= $self->{crit})) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Rate of reading data : " . centreon::esxd::common::simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . centreon::esxd::common::simplify_number($write_counter / 1024 * 8) . " Mb/s"; + $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm new file mode 100644 index 000000000..a4d97db4f --- /dev/null +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -0,0 +1,159 @@ + +package centreon::esxd::cmddatastoreshost; + +use strict; +use warnings; +use File::Basename; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'datastoreshost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($lhost, $warn, $crit) = @_; + + if (!defined($lhost) || $lhost eq "") { + $self->{logger}->writeLogError("ARGS error: need host name"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : ''); + $self->{crit} = (defined($_[2]) ? $_[2] : ''); + $self->{filter_ds} = (defined($_[3]) ? $_[3] : ''); +} + +sub run { + my $self = shift; + + my %valid_ds = (); + my $filter_ok = 0; + if ($self->{filter_ds} ne '') { + foreach (split /,/, $self->{filter_ds}) { + $valid_ds{$_} = 1; + } + } + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lhost}); + my @properties = ('config.fileSystemVolume.mountInfo'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my %uuid_list = (); + my %disk_name = (); + foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { + if ($_->volume->isa('HostVmfsVolume')) { + $uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + #foreach my $extent (@{$_->volume->extent}) { + # $disk_name{$extent->diskName} = $_->volume->name; + #} + } + if ($_->volume->isa('HostNasVolume')) { + $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; + } + } + + # Vsphere >= 4.1 + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, + {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $perfdata = ''; + foreach (keys %uuid_list) { + if ($self->{filter_ds} ne '' and !defined($valid_ds{$uuid_list{$_}})) { + next; + } + if (defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and + defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); + if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $uuid_list{$_} . "' is $read_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $uuid_list{$_} . "' is $write_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + + $filter_ok = 1; + $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; + } + } + + if ($self->{filter_ds} ne '' and $filter_ok == 0) { + $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status). "|Datastore names in filter are unknown.\n"); + return ; + } + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Latency counter: $output_warning"; + } + if ($status == 0) { + $output = "All Datastore latency counters are ok"; + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); +} + +1; diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/lib/cmddatastoresvm.pm new file mode 100644 index 000000000..32b1b66b7 --- /dev/null +++ b/connectors/vmware/lib/cmddatastoresvm.pm @@ -0,0 +1,160 @@ + +package centreon::esxd::cmddatastoresvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'datastoresvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($lvm, $warn, $crit) = @_; + + if (!defined($lvm) || $lvm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm name"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : ''); + $self->{crit} = (defined($_[2]) ? $_[2] : ''); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lvm}); + my @properties = ('datastore'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my @ds_array = (); + foreach my $entity_view (@$result) { + if (defined $entity_view->datastore) { + @ds_array = (@ds_array, @{$entity_view->datastore}); + } + } + @properties = ('info'); + my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties); + if (!defined($result2)) { + return ; + } + + #my %uuid_list = (); + my %disk_name = (); + my %datastore_lun = (); + foreach (@$result2) { + if ($_->info->isa('VmfsDatastoreInfo')) { + #$uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + foreach my $extent (@{$_->info->vmfs->extent}) { + $disk_name{$extent->diskName} = $_->info->vmfs->name; + if (!defined($datastore_lun{$_->info->vmfs->name})) { + %{$datastore_lun{$_->info->vmfs->name}} = ('disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0); + } + } + } + #if ($_->info->isa('NasDatastoreInfo')) { + # Zero disk Info + #} + } + + # Vsphere >= 4.1 + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, + {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + foreach (keys %$values) { + my ($id, $disk_name) = split(/:/); + $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$_}[0]; + } + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $perfdata = ''; + foreach (keys %datastore_lun) { + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + + if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $_ . "' is $read_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $_ . "' is $read_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $_ . "' is $write_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $_ . "' is $write_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + + $perfdata .= " 'riops_" . $_ . "'=" . $read_counter . "iops 'wiops_" . $_ . "'=" . $write_counter . 'iops'; + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Datastore IOPS counter: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Datastore IOPS counter: $output_warning"; + } + if ($status == 0) { + $output = "All Datastore IOPS counters are ok"; + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); +} + +1; diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/lib/cmddatastoreusage.pm new file mode 100644 index 000000000..09739c282 --- /dev/null +++ b/connectors/vmware/lib/cmddatastoreusage.pm @@ -0,0 +1,90 @@ + +package centreon::esxd::cmddatastoreusage; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'datastore-usage'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($ds, $warn, $crit) = @_; + + if (!defined($ds) || $ds eq "") { + $self->{logger}->writeLogError("ARGS error: need datastore name"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{ds} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 80); + $self->{crit} = (defined($_[2]) ? $_[2] : 90); +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{ds}); + my @properties = ('summary'); + + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ""; + if ($$result[0]->summary->accessible == 1) { + my $dsName = $$result[0]->summary->name; + my $capacity = $$result[0]->summary->capacity; + my $free = $$result[0]->summary->freeSpace; + my $pct = ($capacity - $free) / $capacity * 100; + + my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; + my $sizeD = $capacity / 1024 / 1024 / 1024; + + $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; + if ($pct >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($pct > $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + } else { + $output = "Datastore '" . $self->{ds} . "' summary not accessible."; + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdgetmap.pm b/connectors/vmware/lib/cmdgetmap.pm new file mode 100644 index 000000000..ee83bdcfb --- /dev/null +++ b/connectors/vmware/lib/cmdgetmap.pm @@ -0,0 +1,77 @@ + +package centreon::esxd::cmdgetmap; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'getmap'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; +} + +sub run { + my $self = shift; + + my %filters = (); + if (defined($self->{lhost}) and $self->{lhost} ne "") { + %filters = ('name' => $self->{lhost}); + } + my @properties = ('name', 'vm'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + my $output_append = ""; + + foreach my $entity_view (@$result) { + $output .= $output_append . "ESX Host '" . $entity_view->name . "': "; + my @vm_array = (); + if (defined $entity_view->vm) { + @vm_array = (@vm_array, @{$entity_view->vm}); + } + + @properties = ('name', 'summary.runtime.powerState'); + my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + if (!defined($result)) { + return ; + } + + my $output_append2 = ''; + foreach my $vm (@$result2) { + if ($vm->{'summary.runtime.powerState'}->val eq "poweredOn") { + $output .= $output_append2 . "[" . $vm->name . "]"; + $output_append2 = ', '; + } + } + $output_append = ". "; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdhealthhost.pm b/connectors/vmware/lib/cmdhealthhost.pm new file mode 100644 index 000000000..ba864fcb0 --- /dev/null +++ b/connectors/vmware/lib/cmdhealthhost.pm @@ -0,0 +1,122 @@ + +package centreon::esxd::cmdhealthhost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'healthhost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lhost}); + my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output_critical = ''; + my $output_critical_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output = ''; + my $output_append = ''; + my $OKCount = 0; + my $CAlertCount = 0; + my $WAlertCount = 0; + foreach my $entity_view (@$result) { + my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo'}; + my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; + if (!defined($cpuStatusInfo)) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "API error - unable to get cpuStatusInfo"); + } + if (!defined($numericSensorInfo)) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "API error - unable to get numericSensorInfo"); + } + + # CPU + foreach (@$cpuStatusInfo) { + if ($_->status->key =~ /^red$/i) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $CAlertCount++; + } elsif ($_->status->key =~ /^yellow$/i) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $WAlertCount++; + } else { + $OKCount++; + } + } + # Sensor + foreach (@$numericSensorInfo) { + if ($_->healthState->key =~ /^red$/i) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $CAlertCount++; + } elsif ($_->healthState->key =~ /^yellow$/i) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $WAlertCount++; + } else { + $OKCount++; + } + } + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - $CAlertCount health issue(s) found: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - $WAlertCount health issue(s) found: $output_warning"; + } + if ($status == 0) { + $output = "All $OKCount health checks are green"; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdlistdatastore.pm b/connectors/vmware/lib/cmdlistdatastore.pm new file mode 100644 index 000000000..b8b0e901b --- /dev/null +++ b/connectors/vmware/lib/cmdlistdatastore.pm @@ -0,0 +1,57 @@ + +package centreon::esxd::cmdlistdatastore; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'listdatastore'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + return 0; +} + +sub initArgs { + my $self = shift; +} + +sub run { + my $self = shift; + + my %filters = (); + my @properties = ('summary'); + + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Datastore List: '; + my $output_append = ""; + foreach my $datastore (@$result) { + if ($datastore->summary->accessible) { + $output .= $output_append . "'" . $datastore->summary->name . "'"; + $output_append = ', '; + } + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdlisthost.pm b/connectors/vmware/lib/cmdlisthost.pm new file mode 100644 index 000000000..4d44ea733 --- /dev/null +++ b/connectors/vmware/lib/cmdlisthost.pm @@ -0,0 +1,54 @@ + +package centreon::esxd::cmdlisthost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'listhost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + return 0; +} + +sub initArgs { + my $self = shift; +} + +sub run { + my $self = shift; + my %filters = (); + my @properties = ('name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Host List: '; + my $output_append = ""; + + foreach my $entity_view (@$result) { + $output .= $output_append . $entity_view->{name}; + $output_append = ', '; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdlistnichost.pm b/connectors/vmware/lib/cmdlistnichost.pm new file mode 100644 index 000000000..ffc452ae9 --- /dev/null +++ b/connectors/vmware/lib/cmdlistnichost.pm @@ -0,0 +1,68 @@ + +package centreon::esxd::cmdlistnichost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'listnichost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lhost}); + my @properties = ('config.network.pnic'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output_up = 'Nic Up List: '; + my $output_down = 'Nic Down List: '; + my $output_up_append = ""; + my $output_down_append = ""; + foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($_->linkSpeed)) { + $output_up .= $output_up_append . "'" . $_->device . "'"; + $output_up_append = ', '; + } else { + $output_down .= $output_down_append . "'" . $_->device . "'"; + $output_down_append = ', '; + } + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output_up. $output_down.\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdmaintenancehost.pm b/connectors/vmware/lib/cmdmaintenancehost.pm new file mode 100644 index 000000000..8abb4bdcb --- /dev/null +++ b/connectors/vmware/lib/cmdmaintenancehost.pm @@ -0,0 +1,65 @@ + +package centreon::esxd::cmdmaintenancehost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'maintenancehost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($lhost) = @_; + + if (!defined($lhost) || $lhost eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lhost}); + my @properties = ('runtime.inMaintenanceMode'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + foreach my $entity_view (@$result) { + if ($entity_view->{'runtime.inMaintenanceMode'} ne "false") { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $output = "Server " . $self->{lhost} . " is on maintenance mode."; + } else { + $output = "Server " . $self->{lhost} . " is not on maintenance mode."; + } + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdmemhost.pm b/connectors/vmware/lib/cmdmemhost.pm new file mode 100644 index 000000000..8316d42a8 --- /dev/null +++ b/connectors/vmware/lib/cmdmemhost.pm @@ -0,0 +1,96 @@ + +package centreon::esxd::cmdmemhost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'memhost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host, $warn, $crit) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 80); + $self->{crit} = (defined($_[2]) ? $_[2] : 90); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lhost}); + my @properties = ('summary.hardware.memorySize'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'mem.consumed.average', 'instances' => ['']}, + {'label' => 'mem.overhead.average', 'instances' => ['']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])); + my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if ($mem_used * 100 / ($memory_size / 1024) >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($mem_used * 100 / ($memory_size / 1024) >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Memory used : " . centreon::esxd::common::simplify_number($mem_used / 1024 / 1024) . " Go - size : " . centreon::esxd::common::simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . centreon::esxd::common::simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; + $output .= "|used=" . ($mem_used * 1024) . "o;" . centreon::esxd::common::simplify_number($memory_size * $self->{warn} / 100, 0) . ";" . centreon::esxd::common::simplify_number($memory_size * $self->{crit} / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdmemvm.pm b/connectors/vmware/lib/cmdmemvm.pm new file mode 100644 index 000000000..9b0d7835e --- /dev/null +++ b/connectors/vmware/lib/cmdmemvm.pm @@ -0,0 +1,102 @@ + +package centreon::esxd::cmdmemvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'memvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm, $warn, $crit) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm name"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 80); + $self->{crit} = (defined($_[2]) ? $_[2] : 90); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lvm}); + my @properties = ('summary.config.memorySizeMB'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'mem.active.average', 'instances' => ['']}, + {'label' => 'mem.overhead.average', 'instances' => ['']}, + {'label' => 'mem.vmmemctl.average', 'instances' => ['']}, + {'label' => 'mem.consumed.average', 'instances' => ['']}, + {'label' => 'mem.shared.average', 'instances' => ['']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])); + my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])); + my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])); + my $mem_ballooning = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])); + my $mem_shared = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if ($mem_consumed * 100 / ($memory_size / 1024) >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($mem_consumed * 100 / ($memory_size / 1024) >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Memory usage : " . centreon::esxd::common::simplify_number($mem_consumed / 1024 / 1024) . " Go - size : " . centreon::esxd::common::simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . centreon::esxd::common::simplify_number($mem_consumed * 100 / ($memory_size / 1024)) . " %"; + $output .= "|usage=" . ($mem_consumed * 1024) . "o;" . centreon::esxd::common::simplify_number($memory_size * $self->{warn} / 100, 0) . ";" . centreon::esxd::common::simplify_number($memory_size * $self->{crit} / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o" . " ballooning=" . ($mem_ballooning * 1024) . "o" . " shared=" . ($mem_shared * 1024) . "o" . " active=" . ($mem_active * 1024) . "o" ; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm new file mode 100644 index 000000000..8bc542926 --- /dev/null +++ b/connectors/vmware/lib/cmdnethost.pm @@ -0,0 +1,112 @@ + +package centreon::esxd::cmdnethost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'nethost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host, $pnic, $warn, $crit) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + if (!defined($pnic) || $pnic eq "") { + $self->{logger}->writeLogError("ARGS error: need physical nic name"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; + $self->{pnic} = $_[1]; + $self->{warn} = (defined($_[2]) ? $_[2] : 80); + $self->{crit} = (defined($_[3]) ? $_[3] : 90); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lhost}); + my @properties = ('config.network.pnic'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + my %pnic_def = (); + foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($_->linkSpeed)) { + $pnic_def{$_->device} = $_->linkSpeed->speedMb; + } + } + + if (!defined($pnic_def{$self->{pnic}})) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Link '" . $self->{pnic} . "' not exist or down.\n"); + return ; + } + + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'net.received.average', 'instances' => [$self->{pnic}]}, + {'label' => 'net.transmitted.average', 'instances' => [$self->{pnic}]}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{'key'} . ":" . $self->{pnic}}[0])); + my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{'key'} . ":" . $self->{pnic}}[0])); + my $status = 0; # OK + my $output = ''; + + if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{warn} || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{crit} || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) . " %)"; + $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm new file mode 100644 index 000000000..19afe3ebb --- /dev/null +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -0,0 +1,106 @@ + +package centreon::esxd::cmdsnapshotvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'snapshotvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm, $older) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm hostname"); + return 1; + } + if (defined($older) && $older ne '' && $older !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: older arg must be a positive number"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{older} = ((defined($_[1]) and $_[1] ne '') ? $_[1] : -1); + $self->{warn} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); + $self->{crit} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); +} + +sub run { + my $self = shift; + + if ($self->{older} != -1 && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Need to install Date::Parse CPAN Module.\n"); + return ; + } + + my %filters = ('name' => $self->{lvm}); + my @properties = ('snapshot.rootSnapshotList'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = 'Snapshot(s) OK'; + + if (!defined($$result[0]->{'snapshot.rootSnapshotList'})) { + $output = 'No current snapshot.'; + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + return ; + } + + foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { + if ($self->{older} != -1) { + # 2012-09-21T14:16:17.540469Z + my $create_time = Date::Parse::str2time($snapshot->createTime); + if (!defined($create_time)) { + $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't Parse date '" . $snapshot->createTime . "'.\n"); + return ; + } + if (time() - $create_time > $self->{older}) { + if ($self->{warn} == 1) { + $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($self->{crit} == 1) { + $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + } + } elsif ($self->{older} == -1) { + if ($self->{warn} == 1) { + $output = 'There is at least one snapshot.'; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($self->{crit} == 1) { + $output = 'There is at least one snapshot.'; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + } + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdstatushost.pm b/connectors/vmware/lib/cmdstatushost.pm new file mode 100644 index 000000000..a3fcf242f --- /dev/null +++ b/connectors/vmware/lib/cmdstatushost.pm @@ -0,0 +1,81 @@ + +package centreon::esxd::cmdstatushost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'statushost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lhost}); + my @properties = ('summary.overallStatus'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + my %overallStatus = ( + 'gray' => 'status is unknown', + 'green' => 'is OK', + 'red' => 'has a problem', + 'yellow' => 'might have a problem', + ); + my %overallStatusReturn = ( + 'gray' => 'UNKNOWN', + 'green' => 'OK', + 'red' => 'CRITICAL', + 'yellow' => 'WARNING' + ); + + foreach my $entity_view (@$result) { + my $status_esx = $entity_view->{'summary.overallStatus'}->val; + + if (defined($status) && $overallStatus{$status_esx}) { + $output = "The Server '" . $self->{lhost} . "' " . $overallStatus{$status_esx}; + $status = centreon::esxd::common::errors_mask($status, $overallStatusReturn{$status_esx}); + } else { + $output = "Can't interpret data..."; + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + } + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdswaphost.pm b/connectors/vmware/lib/cmdswaphost.pm new file mode 100644 index 000000000..6d27cf6a3 --- /dev/null +++ b/connectors/vmware/lib/cmdswaphost.pm @@ -0,0 +1,94 @@ + +package centreon::esxd::cmdswaphost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'swaphost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($host, $warn, $crit) = @_; + + if (!defined($host) || $host eq "") { + $self->{logger}->writeLogError("ARGS error: need hostname"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 0.8); + $self->{crit} = (defined($_[2]) ? $_[2] : 1); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lhost}); + my @properties = ('name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, + {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])); + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if (($swap_in / 1024) >= $self->{warn} || ($swap_out / 1024) >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if (($swap_in / 1024) >= $self->{crit} || ($swap_out / 1024) >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Swap In : " . centreon::esxd::common::simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . centreon::esxd::common::simplify_number($swap_out / 1024 * 8) . " Mb/s "; + $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdswapvm.pm b/connectors/vmware/lib/cmdswapvm.pm new file mode 100644 index 000000000..2760d268c --- /dev/null +++ b/connectors/vmware/lib/cmdswapvm.pm @@ -0,0 +1,94 @@ + +package centreon::esxd::cmdswapvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'swapvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm, $warn, $crit) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm name"); + return 1; + } + if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : 0.8); + $self->{crit} = (defined($_[2]) ? $_[2] : 1); +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = ('name' => $self->{lvm}); + my @properties = ('name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $$result[0], + [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, + {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], + $self->{obj_esxd}->{perfcounter_speriod}); + + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])); + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); + my $status = 0; # OK + my $output = ''; + + if (($swap_in / 1024) >= $self->{warn} || ($swap_out / 1024) >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if (($swap_in / 1024) >= $self->{crit} || ($swap_out / 1024) >= $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + + $output = "Swap In : " . centreon::esxd::common::simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . centreon::esxd::common::simplify_number($swap_out / 1024 * 8) . " Mb/s "; + $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdtoolsvm.pm b/connectors/vmware/lib/cmdtoolsvm.pm new file mode 100644 index 000000000..9edde29a4 --- /dev/null +++ b/connectors/vmware/lib/cmdtoolsvm.pm @@ -0,0 +1,70 @@ + +package centreon::esxd::cmdtoolsvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'toolsvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm hostname"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lvm}); + my @properties = ('summary.guest.toolsStatus'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ''; + + my $tools_status = lc($$result[0]->{'summary.guest.toolsStatus'}->val); + if ($tools_status eq 'toolsnotinstalled') { + $output = "VMTools not installed on VM '" . $self->{lvm} . "'."; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif ($tools_status eq 'toolsnotrunning') { + $output = "VMTools not running on VM '" . $self->{lvm} . "'."; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif ($tools_status eq 'toolsold') { + $output = "VMTools not up-to-date on VM '" . $self->{lvm} . "'."; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } else { + $output = "VMTools are OK on VM '" . $self->{lvm} . "'."; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmduptimehost.pm b/connectors/vmware/lib/cmduptimehost.pm new file mode 100644 index 000000000..2e951f441 --- /dev/null +++ b/connectors/vmware/lib/cmduptimehost.pm @@ -0,0 +1,73 @@ + +package centreon::esxd::cmduptimehost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'uptimehost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($lhost) = @_; + + if (!defined($lhost) || $lhost eq "") { + $self->{logger}->writeLogError("ARGS error: need host name"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lhost} = $_[0]; +} + +sub run { + my $self = shift; + + if ($self->{obj_esxd}->{module_date_parse_loaded} == 0) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Need to install Date::Parse Perl Module.\n"); + return ; + } + + my %filters = ('name' => $self->{lhost}); + my @properties = ('runtime.bootTime'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $create_time = Date::Parse::str2time($$result[0]->{'runtime.bootTime'}); + if (!defined($create_time)) { + $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't Parse date '" . $$result[0]->{'runtime.bootTime'} . "'.\n"); + return ; + } + my $diff_time = time() - $create_time; + my $days = int($diff_time / 60 / 60 / 24); + + my $output = ''; + my $status = 0; # OK + + $output = "Uptime (in day): $days|uptime=" . $days . "day(s)\n"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/command-countvmhost.pm b/connectors/vmware/lib/command-countvmhost.pm deleted file mode 100644 index 9bf7e097e..000000000 --- a/connectors/vmware/lib/command-countvmhost.pm +++ /dev/null @@ -1,74 +0,0 @@ -sub countvmhost_check_args { - my ($lhost, $warn, $crit) = @_; - if (!defined($lhost) || $lhost eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub countvmhost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : ''); - my $crit = (defined($_[2]) ? $_[2] : ''); - return ($lhost, $warn, $crit); -} - -sub countvmhost_do { - my ($lhost, $warn, $crit) = @_; - - my %filters = ('name' => $lhost); - my @properties = ('vm'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @vm_array = (); - foreach my $entity_view (@$result) { - if (defined $entity_view->vm) { - @vm_array = (@vm_array, @{$entity_view->vm}); - } - } - @properties = ('runtime.powerState'); - $result = get_views(\@vm_array, \@properties); - if (!defined($result)) { - return ; - } - - my $output = ''; - my $status = 0; # OK - my $num_poweron = 0; - - foreach (@$result) { - my $power_value = lc($_->{'runtime.powerState'}->val); - if ($power_value eq 'poweredon') { - $num_poweron++; - } - } - if (defined($crit) && $crit ne "" && ($num_poweron >= $crit)) { - $output = "CRITICAL: $num_poweron VM running."; - $status |= $MYERRORS_MASK{'CRITICAL'}; - } elsif (defined($warn) && $warn ne "" && ($num_poweron >= $warn)) { - $output = "WARNING: $num_poweron VM running."; - $status |= $MYERRORS_MASK{'WARNING'}; - } else { - $output = "OK: $num_poweron VM running."; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output|count=$num_poweron\n"); -} - -1; diff --git a/connectors/vmware/lib/command-cpuhost.pm b/connectors/vmware/lib/command-cpuhost.pm deleted file mode 100644 index 1ff1d4896..000000000 --- a/connectors/vmware/lib/command-cpuhost.pm +++ /dev/null @@ -1,77 +0,0 @@ -sub cpuhost_check_args { - my ($host, $warn, $crit, $light_perfdata) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub cpuhost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - my $light_perfdata = (defined($_[3]) ? $_[3] : 0); - return ($lhost, $warn, $crit, $light_perfdata); -} - -sub cpuhost_do { - my ($lhost, $warn, $crit, $light_perfdata) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('name'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @instances = ('*'); - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'cpu.usage.average', 'instances' => \@instances}], - $perfcounter_speriod); - - my $status = 0; # OK - my $output = ''; - my $total_cpu_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - - if ($total_cpu_average >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($total_cpu_average >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Total Average CPU usage '$total_cpu_average%' on last " . int($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100"; - - foreach my $id (sort { my ($cida, $cia) = split /:/, $a; - my ($cidb, $cib) = split /:/, $b; - $cia = -1 if (!defined($cia) || $cia eq ""); - $cib = -1 if (!defined($cib) || $cib eq ""); - $cia <=> $cib} keys %$values) { - my ($counter_id, $instance) = split /:/, $id; - if ($instance ne "" and $light_perfdata != 1) { - $output .= " cpu$instance=" . simplify_number(convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; - } - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-cpuvm.pm b/connectors/vmware/lib/command-cpuvm.pm deleted file mode 100644 index 67789cc52..000000000 --- a/connectors/vmware/lib/command-cpuvm.pm +++ /dev/null @@ -1,79 +0,0 @@ - -sub cpuvm_check_args { - my ($vm, $warn, $crit) = @_; - if (!defined($vm) || $vm eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub cpuvm_compute_args { - my $lvm = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($lvm, $warn, $crit); -} - -sub cpuvm_do { - my ($lvm, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lvm); - my @properties = ('name'); - my $result = get_entities_host('VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @instances = ('*'); - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'cpu.usage.average', 'instances' => \@instances}, - {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], - $perfcounter_speriod); - - my $status = 0; # OK - my $output = ''; - my $total_cpu_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = simplify_number(convert_number($values->{$perfcounter_cache{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); - - if ($total_cpu_average >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($total_cpu_average >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . int($perfcounter_speriod / 60) . "min | cpu_total=$total_cpu_average%;$warn;$crit;0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; - - foreach my $id (sort { my ($cida, $cia) = split /:/, $a; - my ($cidb, $cib) = split /:/, $b; - $cia = -1 if (!defined($cia) || $cia eq ""); - $cib = -1 if (!defined($cib) || $cib eq ""); - $cia <=> $cib} keys %$values) { - my ($counter_id, $instance) = split /:/, $id; - if ($instance ne "") { - $output .= " cpu" . $instance . "_MHz=" . simplify_number(convert_number($values->{$id}[0])) . "MHz"; - } - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-datastoreio.pm b/connectors/vmware/lib/command-datastoreio.pm deleted file mode 100644 index 01621e955..000000000 --- a/connectors/vmware/lib/command-datastoreio.pm +++ /dev/null @@ -1,68 +0,0 @@ -sub datastoreio_check_args { - my ($ds, $warn, $crit) = @_; - if (!defined($ds) || $ds eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoreio_compute_args { - my $ds = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : ''); - my $crit = (defined($_[2]) ? $_[2] : ''); - return ($ds, $warn, $crit); -} - -sub datastoreio_do { - my ($ds, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('summary.name' => $ds); - my @properties = ('summary.name'); - my $result = get_entities_host('Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'datastore.read.average', 'instances' => ['']}, - {'label' => 'datastore.write.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.read.average'}->{'key'} . ":"}[0])); - my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.write.average'}->{'key'} . ":"}[0])); - - my $status = 0; # OK - my $output = ''; - - if ((defined($warn) && $warn ne "") && ($read_counter >= $warn || $write_counter >= $warn)) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ((defined($crit) && $crit ne "") && ($read_counter >= $crit || $write_counter >= $crit)) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Rate of reading data : " . simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . simplify_number($write_counter / 1024 * 8) . " Mb/s"; - $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-datastoreshost.pm b/connectors/vmware/lib/command-datastoreshost.pm deleted file mode 100644 index b936e4fd0..000000000 --- a/connectors/vmware/lib/command-datastoreshost.pm +++ /dev/null @@ -1,132 +0,0 @@ -sub datastoreshost_check_args { - my ($lhost, $warn, $crit) = @_; - if (!defined($lhost) || $lhost eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoreshost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : ''); - my $crit = (defined($_[2]) ? $_[2] : ''); - my $filter_ds = (defined($_[3]) ? $_[3] : ''); - return ($lhost, $warn, $crit, $filter_ds); -} - -sub datastoreshost_do { - my ($lhost, $warn, $crit, $filter_ds) = @_; - - my %valid_ds = (); - my $filter_ok = 0; - if ($filter_ds ne '') { - foreach (split /,/, $filter_ds) { - $valid_ds{$_} = 1; - } - } - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('config.fileSystemVolume.mountInfo'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my %uuid_list = (); - my %disk_name = (); - foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { - if ($_->volume->isa('HostVmfsVolume')) { - $uuid_list{$_->volume->uuid} = $_->volume->name; - # Not need. We are on Datastore level (not LUN level) - #foreach my $extent (@{$_->volume->extent}) { - # $disk_name{$extent->diskName} = $_->volume->name; - #} - } - if ($_->volume->isa('HostNasVolume')) { - $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; - } - } - - # Vsphere >= 4.1 - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, - {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], - $perfcounter_speriod); - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $perfdata = ''; - foreach (keys %uuid_list) { - if ($filter_ds ne '' and !defined($valid_ds{$uuid_list{$_}})) { - next; - } - if (defined($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and - defined($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { - my $read_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); - my $write_counter = simplify_number(convert_number($values->{$perfcounter_cache{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); - if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - - $filter_ok = 1; - $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; - } - } - - if ($filter_ds ne '' and $filter_ok == 0) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Datastore names in filter are unknown.\n"); - return ; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Latency counter: $output_warning"; - } - if ($status == 0) { - $output = "All Datastore latency counters are ok"; - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); -} - -1; diff --git a/connectors/vmware/lib/command-datastoresvm.pm b/connectors/vmware/lib/command-datastoresvm.pm deleted file mode 100644 index 5da5cf997..000000000 --- a/connectors/vmware/lib/command-datastoresvm.pm +++ /dev/null @@ -1,133 +0,0 @@ -sub datastoresvm_check_args { - my ($lvm, $warn, $crit) = @_; - if (!defined($lvm) || $lvm eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoresvm_compute_args { - my $lvm = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : ''); - my $crit = (defined($_[2]) ? $_[2] : ''); - return ($lvm, $warn, $crit); -} - -sub datastoresvm_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('datastore'); - my $result = get_entities_host('VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @ds_array = (); - foreach my $entity_view (@$result) { - if (defined $entity_view->datastore) { - @ds_array = (@ds_array, @{$entity_view->datastore}); - } - } - @properties = ('info'); - my $result2 = get_views(\@ds_array, \@properties); - if (!defined($result2)) { - return ; - } - - #my %uuid_list = (); - my %disk_name = (); - my %datastore_lun = (); - foreach (@$result2) { - if ($_->info->isa('VmfsDatastoreInfo')) { - #$uuid_list{$_->volume->uuid} = $_->volume->name; - # Not need. We are on Datastore level (not LUN level) - foreach my $extent (@{$_->info->vmfs->extent}) { - $disk_name{$extent->diskName} = $_->info->vmfs->name; - if (!defined($datastore_lun{$_->info->vmfs->name})) { - %{$datastore_lun{$_->info->vmfs->name}} = ('disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0); - } - } - } - #if ($_->info->isa('NasDatastoreInfo')) { - # Zero disk Info - #} - } - - # Vsphere >= 4.1 - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, - {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $perfcounter_speriod); - - foreach (keys %$values) { - my ($id, $disk_name) = split(/:/); - $datastore_lun{$disk_name{$disk_name}}{$perfcounter_cache_reverse{$id}} += $values->{$_}[0]; - } - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $perfdata = ''; - foreach (keys %datastore_lun) { - my $read_counter = simplify_number(convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $perfcounter_speriod)); - my $write_counter = simplify_number(convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $perfcounter_speriod)); - - if (defined($crit) && $crit ne "" && ($read_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $_ . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($read_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $_ . "' is $read_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (defined($crit) && $crit ne "" && ($write_counter >= $crit)) { - output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $_ . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } elsif (defined($warn) && $warn ne "" && ($write_counter >= $warn)) { - output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $_ . "' is $write_counter ms"); - $status |= $MYERRORS_MASK{'WARNING'}; - } - - $perfdata .= " 'riops_" . $_ . "'=" . $read_counter . "iops 'wiops_" . $_ . "'=" . $write_counter . 'iops'; - } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Datastore IOPS counter: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Datastore IOPS counter: $output_warning"; - } - if ($status == 0) { - $output = "All Datastore IOPS counters are ok"; - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output|$perfdata\n"); -} - -1; diff --git a/connectors/vmware/lib/command-datastoreusage.pm b/connectors/vmware/lib/command-datastoreusage.pm deleted file mode 100644 index 1d5606ca6..000000000 --- a/connectors/vmware/lib/command-datastoreusage.pm +++ /dev/null @@ -1,64 +0,0 @@ -sub datastoreusage_check_args { - my ($ds, $warn, $crit) = @_; - if (!defined($ds) || $ds eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need datastore name\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub datastoreusage_compute_args { - my $ds = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($ds, $warn, $crit); -} - -sub datastoreusage_do { - my ($ds, $warn, $crit) = @_; - my %filters = ('name' => $ds); - my @properties = ('summary'); - - my $result = get_entities_host('Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ""; - if ($$result[0]->summary->accessible == 1) { - my $dsName = $$result[0]->summary->name; - my $capacity = $$result[0]->summary->capacity; - my $free = $$result[0]->summary->freeSpace; - my $pct = ($capacity - $free) / $capacity * 100; - - my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; - my $sizeD = $capacity / 1024 / 1024 / 1024; - - $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; - if ($pct >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($pct > $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - } else { - $output = "Datastore '$ds' summary not accessible."; - $status |= $MYERRORS_MASK{'UNKNOWN'}; - } - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-getmap.pm b/connectors/vmware/lib/command-getmap.pm deleted file mode 100644 index 70bd115f8..000000000 --- a/connectors/vmware/lib/command-getmap.pm +++ /dev/null @@ -1,53 +0,0 @@ - -sub getmap_check_args { - return 0; -} - -sub getmap_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub getmap_do { - my ($lhost) = @_; - my %filters = (); - if (defined($lhost) and $lhost ne "") { - %filters = ('name' => $lhost); - } - my @properties = ('name', 'vm'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - my $output_append = ""; - - foreach my $entity_view (@$result) { - $output .= $output_append . "ESX Host '" . $entity_view->name . "': "; - my @vm_array = (); - if (defined $entity_view->vm) { - @vm_array = (@vm_array, @{$entity_view->vm}); - } - - @properties = ('name', 'summary.runtime.powerState'); - my $result2 = get_views(\@vm_array, \@properties); - if (!defined($result)) { - return ; - } - - my $output_append2 = ''; - foreach my $vm (@$result2) { - if ($vm->{'summary.runtime.powerState'}->val eq "poweredOn") { - $output .= $output_append2 . "[" . $vm->name . "]"; - $output_append2 = ', '; - } - } - $output_append = ". "; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-healthhost.pm b/connectors/vmware/lib/command-healthhost.pm deleted file mode 100644 index 497781a91..000000000 --- a/connectors/vmware/lib/command-healthhost.pm +++ /dev/null @@ -1,97 +0,0 @@ -sub healthhost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub healthhost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub healthhost_do { - my ($lhost) = @_; - - my %filters = ('name' => $lhost); - my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output_critical = ''; - my $output_critical_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output = ''; - my $output_append = ''; - my $OKCount = 0; - my $CAlertCount = 0; - my $WAlertCount = 0; - foreach my $entity_view (@$result) { - my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo'}; - my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; - if (!defined($cpuStatusInfo)) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - output_add(\$output_critical, \$output_critical_append, ", ", - "API error - unable to get cpuStatusInfo"); - } - if (!defined($numericSensorInfo)) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - output_add(\$output_critical, \$output_critical_append, ", ", - "API error - unable to get numericSensorInfo"); - } - - # CPU - foreach (@$cpuStatusInfo) { - if ($_->status->key =~ /^red$/i) { - output_add(\$output_critical, \$output_critical_append, ", ", - $_->name . ": " . $_->status->summary); - $status |= $MYERRORS_MASK{'CRITICAL'}; - $CAlertCount++; - } elsif ($_->status->key =~ /^yellow$/i) { - output_add(\$output_warning, \$output_warning_append, ", ", - $_->name . ": " . $_->status->summary); - $status |= $MYERRORS_MASK{'WARNING'}; - $WAlertCount++; - } else { - $OKCount++; - } - } - # Sensor - foreach (@$numericSensorInfo) { - if ($_->healthState->key =~ /^red$/i) { - output_add(\$output_critical, \$output_critical_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status |= $MYERRORS_MASK{'CRITICAL'}; - $CAlertCount++; - } elsif ($_->healthState->key =~ /^yellow$/i) { - output_add(\$output_warning, \$output_warning_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status |= $MYERRORS_MASK{'WARNING'}; - $WAlertCount++; - } else { - $OKCount++; - } - } - } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $CAlertCount health issue(s) found: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $WAlertCount health issue(s) found: $output_warning"; - } - if ($status == 0) { - $output = "All $OKCount health checks are green"; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-listdatastore.pm b/connectors/vmware/lib/command-listdatastore.pm deleted file mode 100644 index fdd4773ac..000000000 --- a/connectors/vmware/lib/command-listdatastore.pm +++ /dev/null @@ -1,32 +0,0 @@ -sub listdatastore_check_args { - return 0; -} - -sub listdatastore_compute_args { - return undef; -} - -sub listdatastore_do { - my ($ds, $warn, $crit) = @_; - my %filters = (); - my @properties = ('summary'); - - my $result = get_entities_host('Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Datastore List: '; - my $output_append = ""; - foreach my $datastore (@$result) { - if ($datastore->summary->accessible) { - $output .= $output_append . "'" . $datastore->summary->name . "'"; - $output_append = ', '; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-listhost.pm b/connectors/vmware/lib/command-listhost.pm deleted file mode 100644 index 30769a05b..000000000 --- a/connectors/vmware/lib/command-listhost.pm +++ /dev/null @@ -1,30 +0,0 @@ - -sub listhost_check_args { - return 0; -} - -sub listhost_compute_args { - return undef; -} - -sub listhost_do { - my %filters = (); - my @properties = ('name'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Host List: '; - my $output_append = ""; - - foreach my $entity_view (@$result) { - $output .= $output_append . $entity_view->{name}; - $output_append = ', '; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-listnichost.pm b/connectors/vmware/lib/command-listnichost.pm deleted file mode 100644 index 03ad23bc0..000000000 --- a/connectors/vmware/lib/command-listnichost.pm +++ /dev/null @@ -1,43 +0,0 @@ - -sub listnichost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub listnichost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub listnichost_do { - my ($lhost) = @_; - my %filters = ('name' => $lhost); - my @properties = ('config.network.pnic'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output_up = 'Nic Up List: '; - my $output_down = 'Nic Down List: '; - my $output_up_append = ""; - my $output_down_append = ""; - foreach (@{$$result[0]->{'config.network.pnic'}}) { - if (defined($_->linkSpeed)) { - $output_up .= $output_up_append . "'" . $_->device . "'"; - $output_up_append = ', '; - } else { - $output_down .= $output_down_append . "'" . $_->device . "'"; - $output_down_append = ', '; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output_up. $output_down.\n"); -} - -1; diff --git a/connectors/vmware/lib/command-maintenancehost.pm b/connectors/vmware/lib/command-maintenancehost.pm deleted file mode 100644 index b02f96e9a..000000000 --- a/connectors/vmware/lib/command-maintenancehost.pm +++ /dev/null @@ -1,39 +0,0 @@ -sub maintenancehost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub maintenancehost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub maintenancehost_do { - my ($lhost) = @_; - my %filters = ('name' => $lhost); - my @properties = ('runtime.inMaintenanceMode'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - - foreach my $entity_view (@$result) { - if ($entity_view->{'runtime.inMaintenanceMode'} ne "false") { - $status |= $MYERRORS_MASK{'CRITICAL'}; - $output = "Server $lhost is on maintenance mode."; - } else { - $output = "Server $lhost is not on maintenance mode."; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-memhost.pm b/connectors/vmware/lib/command-memhost.pm deleted file mode 100644 index b57494a93..000000000 --- a/connectors/vmware/lib/command-memhost.pm +++ /dev/null @@ -1,70 +0,0 @@ -sub memhost_check_args { - my ($host, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub memhost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($lhost, $warn, $crit); -} - -sub memhost_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('summary.hardware.memorySize'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; - - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'mem.consumed.average', 'instances' => ['']}, - {'label' => 'mem.overhead.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $mem_used = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); - my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if ($mem_used * 100 / ($memory_size / 1024) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($mem_used * 100 / ($memory_size / 1024) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Memory used : " . simplify_number($mem_used / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; - $output .= "|used=" . ($mem_used * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-memvm.pm b/connectors/vmware/lib/command-memvm.pm deleted file mode 100644 index 3d184120c..000000000 --- a/connectors/vmware/lib/command-memvm.pm +++ /dev/null @@ -1,75 +0,0 @@ -sub memvm_check_args { - my ($vm, $warn, $crit) = @_; - if (!defined($vm) || $vm eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub memvm_compute_args { - my $lvm = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 80); - my $crit = (defined($_[2]) ? $_[2] : 90); - return ($lvm, $warn, $crit); -} - -sub memvm_do { - my ($lvm, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lvm); - my @properties = ('summary.config.memorySizeMB'); - my $result = get_entities_host('VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'mem.active.average', 'instances' => ['']}, - {'label' => 'mem.overhead.average', 'instances' => ['']}, - {'label' => 'mem.vmmemctl.average', 'instances' => ['']}, - {'label' => 'mem.consumed.average', 'instances' => ['']}, - {'label' => 'mem.shared.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $mem_consumed = simplify_number(convert_number($values->{$perfcounter_cache{'mem.consumed.average'}->{'key'} . ":"}[0])); - my $mem_active = simplify_number(convert_number($values->{$perfcounter_cache{'mem.active.average'}->{'key'} . ":"}[0])); - my $mem_overhead = simplify_number(convert_number($values->{$perfcounter_cache{'mem.overhead.average'}->{'key'} . ":"}[0])); - my $mem_ballooning = simplify_number(convert_number($values->{$perfcounter_cache{'mem.vmmemctl.average'}->{'key'} . ":"}[0])); - my $mem_shared = simplify_number(convert_number($values->{$perfcounter_cache{'mem.shared.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if ($mem_consumed * 100 / ($memory_size / 1024) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($mem_consumed * 100 / ($memory_size / 1024) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Memory usage : " . simplify_number($mem_consumed / 1024 / 1024) . " Go - size : " . simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . simplify_number($mem_consumed * 100 / ($memory_size / 1024)) . " %"; - $output .= "|usage=" . ($mem_consumed * 1024) . "o;" . simplify_number($memory_size * $warn / 100, 0) . ";" . simplify_number($memory_size * $crit / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o" . " ballooning=" . ($mem_ballooning * 1024) . "o" . " shared=" . ($mem_shared * 1024) . "o" . " active=" . ($mem_active * 1024) . "o" ; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-nethost.pm b/connectors/vmware/lib/command-nethost.pm deleted file mode 100644 index 510eb8a98..000000000 --- a/connectors/vmware/lib/command-nethost.pm +++ /dev/null @@ -1,86 +0,0 @@ - -sub nethost_check_args { - my ($host, $pnic, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (!defined($pnic) || $pnic eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need physical nic name\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub nethost_compute_args { - my $lhost = $_[0]; - my $pnic = $_[1]; - my $warn = (defined($_[2]) ? $_[2] : 80); - my $crit = (defined($_[3]) ? $_[3] : 90); - return ($lhost, $pnic, $warn, $crit); -} - -sub nethost_do { - my ($lhost, $pnic, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('config.network.pnic'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - my %pnic_def = (); - foreach (@{$$result[0]->{'config.network.pnic'}}) { - if (defined($_->linkSpeed)) { - $pnic_def{$_->device} = $_->linkSpeed->speedMb; - } - } - - if (!defined($pnic_def{$pnic})) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Link '$pnic' not exist or down.\n"); - return ; - } - - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'net.received.average', 'instances' => [$pnic]}, - {'label' => 'net.transmitted.average', 'instances' => [$pnic]}], - $perfcounter_speriod); - - my $traffic_in = simplify_number(convert_number($values->{$perfcounter_cache{'net.received.average'}->{'key'} . ":" . $pnic}[0])); - my $traffic_out = simplify_number(convert_number($values->{$perfcounter_cache{'net.transmitted.average'}->{'key'} . ":" . $pnic}[0])); - my $status = 0; # OK - my $output = ''; - - if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Traffic In : " . simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %), Out : " . simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$pnic}) . " %)"; - $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-snapshotvm.pm b/connectors/vmware/lib/command-snapshotvm.pm deleted file mode 100644 index 0d16c4fc8..000000000 --- a/connectors/vmware/lib/command-snapshotvm.pm +++ /dev/null @@ -1,83 +0,0 @@ - -sub snapshotvm_check_args { - my ($vm, $older) = @_; - if (!defined($vm) || $vm eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm hostname\n"); - return 1; - } - if (defined($older) && $older ne '' && $older !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: older arg must be a positive number\n"); - return 1; - } - return 0; -} - -sub snapshotvm_compute_args { - my $lvm = $_[0]; - my $older = ((defined($_[1]) and $_[1] ne '') ? $_[1] : -1); - my $warn = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); - my $crit = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); - return ($lvm, $older, $warn, $crit); -} - -sub snapshotvm_do { - my ($lvm, $older, $warn, $crit) = @_; - - if ($older != -1 && $module_date_parse_loaded == 0) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 CPAN Module.\n"); - return ; - } - - my %filters = ('name' => $lvm); - my @properties = ('snapshot.rootSnapshotList'); - my $result = get_entities_host('VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Snapshot(s) OK'; - - if (!defined($$result[0]->{'snapshot.rootSnapshotList'})) { - $output = 'No current snapshot.'; - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); - return ; - } - - foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { - if ($older != -1) { - if ($module_date_parse_loaded == 0) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 Perl Module.\n"); - return ; - } - - # 2012-09-21T14:16:17.540469Z - my $create_time = DateTime::Format::ISO8601->parse_datetime($snapshot->createTime); - if (time() - $create_time->epoch > $older) { - if ($warn == 1) { - $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($crit == 1) { - $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - } - } elsif ($older == -1) { - if ($warn == 1) { - $output = 'There is at least one snapshot.'; - $status |= $MYERRORS_MASK{'WARNING'}; - } - if ($crit == 1) { - $output = 'There is at least one snapshot.'; - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-statushost.pm b/connectors/vmware/lib/command-statushost.pm deleted file mode 100644 index b1895175c..000000000 --- a/connectors/vmware/lib/command-statushost.pm +++ /dev/null @@ -1,57 +0,0 @@ -sub statushost_check_args { - my ($host) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - return 0; -} - -sub statushost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub statushost_do { - my ($lhost) = @_; - my %filters = ('name' => $lhost); - my @properties = ('summary.overallStatus'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - - my %overallStatus = ( - 'gray' => 'status is unknown', - 'green' => 'is OK', - 'red' => 'has a problem', - 'yellow' => 'might have a problem', - ); - my %overallStatusReturn = ( - 'gray' => 'UNKNOWN', - 'green' => 'OK', - 'red' => 'CRITICAL', - 'yellow' => 'WARNING' - ); - - foreach my $entity_view (@$result) { - my $status_esx = $entity_view->{'summary.overallStatus'}->val; - - if (defined($status) && $overallStatus{$status_esx}) { - $output = "The Server '$lhost' " . $overallStatus{$status_esx}; - if ($MYERRORS_MASK{$overallStatusReturn{$status_esx}} != 0) { - $status |= $MYERRORS_MASK{$overallStatusReturn{$status_esx}}; - } - } else { - $output = "Can't interpret data..."; - $status |= $MYERRORS_MASK{'UNKNOWN'}; - } - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-swaphost.pm b/connectors/vmware/lib/command-swaphost.pm deleted file mode 100644 index 089e193d6..000000000 --- a/connectors/vmware/lib/command-swaphost.pm +++ /dev/null @@ -1,67 +0,0 @@ -sub swaphost_check_args { - my ($host, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need hostname\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub swaphost_compute_args { - my $lhost = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 0.8); - my $crit = (defined($_[2]) ? $_[2] : 1); - return ($lhost, $warn, $crit); -} - -sub swaphost_do { - my ($lhost, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lhost); - my @properties = ('name'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, - {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $swap_in = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapinRate.average'}->{'key'} . ":"}[0])); - my $swap_out = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if (($swap_in / 1024) >= $warn || ($swap_out / 1024) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (($swap_in / 1024) >= $crit || ($swap_out / 1024) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; - $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-swapvm.pm b/connectors/vmware/lib/command-swapvm.pm deleted file mode 100644 index 7a4d24a43..000000000 --- a/connectors/vmware/lib/command-swapvm.pm +++ /dev/null @@ -1,67 +0,0 @@ -sub swapvm_check_args { - my ($vm, $warn, $crit) = @_; - if (!defined($vm) || $vm eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm name\n"); - return 1; - } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be a positive number\n"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: crit threshold must be a positive number\n"); - return 1; - } - if (defined($warn) && defined($crit) && $warn > $crit) { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: warn threshold must be lower than crit threshold\n"); - return 1; - } - return 0; -} - -sub swapvm_compute_args { - my $lvm = $_[0]; - my $warn = (defined($_[1]) ? $_[1] : 0.8); - my $crit = (defined($_[2]) ? $_[2] : 1); - return ($lvm, $warn, $crit); -} - -sub swapvm_do { - my ($lvm, $warn, $crit) = @_; - if (!($perfcounter_speriod > 0)) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $lvm); - my @properties = ('name'); - my $result = get_entities_host('VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $values = generic_performance_values_historic($$result[0], - [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, - {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], - $perfcounter_speriod); - - my $swap_in = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapinRate.average'}->{'key'} . ":"}[0])); - my $swap_out = simplify_number(convert_number($values->{$perfcounter_cache{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if (($swap_in / 1024) >= $warn || ($swap_out / 1024) >= $warn) { - $status |= $MYERRORS_MASK{'WARNING'}; - } - if (($swap_in / 1024) >= $crit || ($swap_out / 1024) >= $crit) { - $status |= $MYERRORS_MASK{'CRITICAL'}; - } - - $output = "Swap In : " . simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . simplify_number($swap_out / 1024 * 8) . " Mb/s "; - $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-toolsvm.pm b/connectors/vmware/lib/command-toolsvm.pm deleted file mode 100644 index f3808dd11..000000000 --- a/connectors/vmware/lib/command-toolsvm.pm +++ /dev/null @@ -1,46 +0,0 @@ - -sub toolsvm_check_args { - my ($vm) = @_; - if (!defined($vm) || $vm eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need vm hostname\n"); - return 1; - } - return 0; -} - -sub toolsvm_compute_args { - my $lvm = $_[0]; - return ($lvm); -} - -sub toolsvm_do { - my ($lvm) = @_; - - my %filters = ('name' => $lvm); - my @properties = ('summary.guest.toolsStatus'); - my $result = get_entities_host('VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - - my $tools_status = lc($$result[0]->{'summary.guest.toolsStatus'}->val); - if ($tools_status eq 'toolsnotinstalled') { - $output = "VMTools not installed on VM '$lvm'."; - $status |= $MYERRORS_MASK{'CRITICAL'}; - } elsif ($tools_status eq 'toolsnotrunning') { - $output = "VMTools not running on VM '$lvm'."; - $status |= $MYERRORS_MASK{'CRITICAL'}; - } elsif ($tools_status eq 'toolsold') { - $output = "VMTools not up-to-date on VM '$lvm'."; - $status |= $MYERRORS_MASK{'WARNING'}; - } else { - $output = "VMTools are OK on VM '$lvm'."; - } - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/command-uptimehost.pm b/connectors/vmware/lib/command-uptimehost.pm deleted file mode 100644 index 71a7784d5..000000000 --- a/connectors/vmware/lib/command-uptimehost.pm +++ /dev/null @@ -1,43 +0,0 @@ -sub uptimehost_check_args { - my ($lhost) = @_; - if (!defined($lhost) || $lhost eq "") { - writeLogFile(LOG_ESXD_ERROR, "ARGS error: need host name\n"); - return 1; - } - return 0; -} - -sub uptimehost_compute_args { - my $lhost = $_[0]; - return ($lhost); -} - -sub uptimehost_do { - my ($lhost) = @_; - - my %filters = ('name' => $lhost); - my @properties = ('runtime.bootTime'); - my $result = get_entities_host('HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - if ($module_date_parse_loaded == 0) { - my $status |= $MYERRORS_MASK{'UNKNOWN'}; - print_response($ERRORS{$MYERRORS{$status}} . "|Need to install DateTime::Format::ISO8601 Perl Module.\n"); - return ; - } - - my $create_time = DateTime::Format::ISO8601->parse_datetime($$result[0]->{'runtime.bootTime'}); - my $diff_time = time() - $create_time->epoch; - my $days = int($diff_time / 60 / 60 / 24); - - my $output = ''; - my $status = 0; # OK - - $output = "Uptime (in day): $days|uptime=" . $days . "day(s)\n"; - - print_response($ERRORS{$MYERRORS{$status}} . "|$output\n"); -} - -1; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 016446fc7..3a0add393 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -25,228 +25,228 @@ sub get_status { } 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; + 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; + 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; + 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"); + my ($number, $cnt) = @_; + $cnt = 2 if (!defined($cnt)); + return sprintf("%.${cnt}f", "$number"); } sub convert_number { - my ($number) = shift(@_); - $number =~ s/\,/\./; - return $number; + my ($number) = shift(@_); + $number =~ s/\,/\./; + return $number; } sub get_views { my $obj_esxd = shift; - my $results; + 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; + 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; + 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; + 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; + my ($obj_esxd, $view, $perfs, $interval) = @_; + my $counter = 0; + my %results; - eval { - my @perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); + eval { + my @perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); - my $perf_query_spec; + 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]); + 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]); + (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, + 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, + 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; + ); + #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; - } + 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; + 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; - } - } + 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; + # 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; + 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) { + 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; + $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"); + 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; From 87006e17ea76f37f8dbe9d27f11fd9f96a02ec51 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 2 Jul 2013 08:56:22 +0000 Subject: [PATCH 041/447] Ref #5494 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@59 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreonesxd.pm | 2 ++ connectors/vmware/lib/cmdcpuvm.pm | 6 +++- connectors/vmware/lib/cmddatastoreio.pm | 4 ++- connectors/vmware/lib/cmddatastoresvm.pm | 6 +++- connectors/vmware/lib/cmddatastoreusage.pm | 34 ++++++++++------------ connectors/vmware/lib/cmdmemvm.pm | 6 +++- connectors/vmware/lib/cmdswapvm.pm | 6 +++- connectors/vmware/lib/cmdtoolsvm.pm | 7 ++++- connectors/vmware/lib/common.pm | 33 +++++++++++++++++++++ 9 files changed, 80 insertions(+), 24 deletions(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 0eeecee2c..c995bdec4 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -67,6 +67,8 @@ sub new { timeout_kill => 30, refresh_keeper_session => 15, port => 5700, + datastore_state_error => 'UNKNOWN', + vm_state_error => 'UNKNOWN', vsphere_server => { #'default' => {'url' => 'https://XXXXXX/sdk', # 'username' => 'XXXXX', diff --git a/connectors/vmware/lib/cmdcpuvm.pm b/connectors/vmware/lib/cmdcpuvm.pm index 16304b158..85b79904f 100644 --- a/connectors/vmware/lib/cmdcpuvm.pm +++ b/connectors/vmware/lib/cmdcpuvm.pm @@ -61,11 +61,15 @@ sub run { } my %filters = ('name' => $self->{lvm}); - my @properties = ('name'); + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, + $$result[0]->{'runtime.connectionState'}->val, + $$result[0]->{'runtime.powerState'}->val) == 0); my @instances = ('*'); diff --git a/connectors/vmware/lib/cmddatastoreio.pm b/connectors/vmware/lib/cmddatastoreio.pm index 349d1f0c6..d4563b806 100644 --- a/connectors/vmware/lib/cmddatastoreio.pm +++ b/connectors/vmware/lib/cmddatastoreio.pm @@ -61,11 +61,13 @@ sub run { } my %filters = ('summary.name' => $self->{ds}); - my @properties = ('summary.name'); + my @properties = ('summary.name', 'summary.accessible'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->{'summary.accessible'}) == 0); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/lib/cmddatastoresvm.pm index 32b1b66b7..549b6ebb7 100644 --- a/connectors/vmware/lib/cmddatastoresvm.pm +++ b/connectors/vmware/lib/cmddatastoresvm.pm @@ -61,11 +61,15 @@ sub run { } my %filters = ('name' => $self->{lvm}); - my @properties = ('datastore'); + my @properties = ('datastore', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, + $$result[0]->{'runtime.connectionState'}->val, + $$result[0]->{'runtime.powerState'}->val) == 0); my @ds_array = (); foreach my $entity_view (@$result) { diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/lib/cmddatastoreusage.pm index 09739c282..e88981db3 100644 --- a/connectors/vmware/lib/cmddatastoreusage.pm +++ b/connectors/vmware/lib/cmddatastoreusage.pm @@ -61,28 +61,26 @@ sub run { if (!defined($result)) { return ; } + + return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->summary->accessible) == 0); my $status = 0; # OK my $output = ""; - if ($$result[0]->summary->accessible == 1) { - my $dsName = $$result[0]->summary->name; - my $capacity = $$result[0]->summary->capacity; - my $free = $$result[0]->summary->freeSpace; - my $pct = ($capacity - $free) / $capacity * 100; - - my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; - my $sizeD = $capacity / 1024 / 1024 / 1024; - $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; - if ($pct >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if ($pct > $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } - } else { - $output = "Datastore '" . $self->{ds} . "' summary not accessible."; - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + my $dsName = $$result[0]->summary->name; + my $capacity = $$result[0]->summary->capacity; + my $free = $$result[0]->summary->freeSpace; + my $pct = ($capacity - $free) / $capacity * 100; + + my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; + my $sizeD = $capacity / 1024 / 1024 / 1024; + + $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; + if ($pct >= $self->{warn}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($pct > $self->{crit}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); } $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } diff --git a/connectors/vmware/lib/cmdmemvm.pm b/connectors/vmware/lib/cmdmemvm.pm index 9b0d7835e..801abbcc1 100644 --- a/connectors/vmware/lib/cmdmemvm.pm +++ b/connectors/vmware/lib/cmdmemvm.pm @@ -61,11 +61,15 @@ sub run { } my %filters = ('name' => $self->{lvm}); - my @properties = ('summary.config.memorySizeMB'); + my @properties = ('summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, + $$result[0]->{'runtime.connectionState'}->val, + $$result[0]->{'runtime.powerState'}->val) == 0); my $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; diff --git a/connectors/vmware/lib/cmdswapvm.pm b/connectors/vmware/lib/cmdswapvm.pm index 2760d268c..4db072210 100644 --- a/connectors/vmware/lib/cmdswapvm.pm +++ b/connectors/vmware/lib/cmdswapvm.pm @@ -61,11 +61,15 @@ sub run { } my %filters = ('name' => $self->{lvm}); - my @properties = ('name'); + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, + $$result[0]->{'runtime.connectionState'}->val, + $$result[0]->{'runtime.powerState'}->val) == 0); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], diff --git a/connectors/vmware/lib/cmdtoolsvm.pm b/connectors/vmware/lib/cmdtoolsvm.pm index 9edde29a4..442778631 100644 --- a/connectors/vmware/lib/cmdtoolsvm.pm +++ b/connectors/vmware/lib/cmdtoolsvm.pm @@ -41,12 +41,17 @@ sub run { my $self = shift; my %filters = ('name' => $self->{lvm}); - my @properties = ('summary.guest.toolsStatus'); + my @properties = ('summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } + return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, + $$result[0]->{'runtime.connectionState'}->val, + $$result[0]->{'runtime.powerState'}->val) == 0); + + my $status = 0; # OK my $output = ''; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 3a0add393..b0c092ce3 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -231,6 +231,39 @@ sub get_entities_host { return $entity_views; } +sub datastore_state { + my ($obj_esxd, $ds, $accessible) = @_; + + if ($accessible !~ /^true|1$/) { + my $output = "Datastore '" . $ds . "' not accessible. Can be disconnected."; + my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{datastore_state_error}); + $obj_esxd->print_response(get_status($status) . "|$output\n"); + return 0; + } + + return 1; +} + +sub vm_state { + my ($obj_esxd, $vm, $connection_state, $power_state) = @_; + + if ($connection_state !~ /^connected$/i) { + my $output = "VM '" . $vm . "' not connected. Current Connection State: '$connection_state'."; + my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error}); + $obj_esxd->print_response(get_status($status) . "|$output\n"); + return 0; + } + + if ($power_state !~ /^poweredOn$/i) { + my $output = "VM '" . $vm . "' not running. Current Power State: '$power_state'."; + my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error}); + $obj_esxd->print_response(get_status($status) . "|$output\n"); + return 0; + } + + return 1; +} + sub stats_info { my ($obj_esxd, $rh, $current_fileno, $args) = @_; my $output; From 66b27cab268a89b19ac73361bff9add1fe5ac46c Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 2 Jul 2013 09:14:59 +0000 Subject: [PATCH 042/447] Ref #5494 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@60 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreonesxd.pm | 1 + connectors/vmware/lib/cmdcountvmhost.pm | 5 ++++- connectors/vmware/lib/cmdcpuhost.pm | 5 ++++- connectors/vmware/lib/cmddatastoreshost.pm | 5 ++++- connectors/vmware/lib/cmdhealthhost.pm | 6 +++++- connectors/vmware/lib/cmdmemhost.pm | 5 ++++- connectors/vmware/lib/cmdnethost.pm | 6 +++++- connectors/vmware/lib/cmdstatushost.pm | 5 ++++- connectors/vmware/lib/cmdswaphost.pm | 5 ++++- connectors/vmware/lib/cmduptimehost.pm | 7 +++++-- connectors/vmware/lib/common.pm | 13 +++++++++++++ 11 files changed, 53 insertions(+), 10 deletions(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index c995bdec4..7b5a15d04 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -69,6 +69,7 @@ sub new { port => 5700, datastore_state_error => 'UNKNOWN', vm_state_error => 'UNKNOWN', + host_state_error => 'UNKNOWN', vsphere_server => { #'default' => {'url' => 'https://XXXXXX/sdk', # 'username' => 'XXXXX', diff --git a/connectors/vmware/lib/cmdcountvmhost.pm b/connectors/vmware/lib/cmdcountvmhost.pm index b639c2b96..f9f998467 100644 --- a/connectors/vmware/lib/cmdcountvmhost.pm +++ b/connectors/vmware/lib/cmdcountvmhost.pm @@ -55,11 +55,14 @@ sub run { my $self = shift; my %filters = ('name' => $self->{lhost}); - my @properties = ('vm'); + my @properties = ('vm', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); my @vm_array = (); foreach my $entity_view (@$result) { diff --git a/connectors/vmware/lib/cmdcpuhost.pm b/connectors/vmware/lib/cmdcpuhost.pm index ecbcc326e..01e4f1a07 100644 --- a/connectors/vmware/lib/cmdcpuhost.pm +++ b/connectors/vmware/lib/cmdcpuhost.pm @@ -62,12 +62,15 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('name'); + my @properties = ('name', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); + my @instances = ('*'); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index a4d97db4f..0240623a9 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -70,11 +70,14 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('config.fileSystemVolume.mountInfo'); + my @properties = ('config.fileSystemVolume.mountInfo', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); my %uuid_list = (); my %disk_name = (); diff --git a/connectors/vmware/lib/cmdhealthhost.pm b/connectors/vmware/lib/cmdhealthhost.pm index ba864fcb0..82bc8e1ed 100644 --- a/connectors/vmware/lib/cmdhealthhost.pm +++ b/connectors/vmware/lib/cmdhealthhost.pm @@ -41,12 +41,16 @@ sub run { my $self = shift; my %filters = ('name' => $self->{lhost}); - my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'); + my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', + 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); + my $status = 0; # OK my $output_critical = ''; my $output_critical_append = ''; diff --git a/connectors/vmware/lib/cmdmemhost.pm b/connectors/vmware/lib/cmdmemhost.pm index 8316d42a8..975736bb3 100644 --- a/connectors/vmware/lib/cmdmemhost.pm +++ b/connectors/vmware/lib/cmdmemhost.pm @@ -61,11 +61,14 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('summary.hardware.memorySize'); + my @properties = ('summary.hardware.memorySize', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index 8bc542926..e3a996259 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -66,11 +66,15 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('config.network.pnic'); + my @properties = ('config.network.pnic', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); + my %pnic_def = (); foreach (@{$$result[0]->{'config.network.pnic'}}) { if (defined($_->linkSpeed)) { diff --git a/connectors/vmware/lib/cmdstatushost.pm b/connectors/vmware/lib/cmdstatushost.pm index a3fcf242f..7757110c9 100644 --- a/connectors/vmware/lib/cmdstatushost.pm +++ b/connectors/vmware/lib/cmdstatushost.pm @@ -41,11 +41,14 @@ sub run { my $self = shift; my %filters = ('name' => $self->{lhost}); - my @properties = ('summary.overallStatus'); + my @properties = ('summary.overallStatus', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); my $status = 0; # OK my $output = ''; diff --git a/connectors/vmware/lib/cmdswaphost.pm b/connectors/vmware/lib/cmdswaphost.pm index 6d27cf6a3..15d6b7812 100644 --- a/connectors/vmware/lib/cmdswaphost.pm +++ b/connectors/vmware/lib/cmdswaphost.pm @@ -61,11 +61,14 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('name'); + my @properties = ('name', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], diff --git a/connectors/vmware/lib/cmduptimehost.pm b/connectors/vmware/lib/cmduptimehost.pm index 2e951f441..b1457a400 100644 --- a/connectors/vmware/lib/cmduptimehost.pm +++ b/connectors/vmware/lib/cmduptimehost.pm @@ -47,15 +47,18 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('runtime.bootTime'); + my @properties = ('runtime.bootTime', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + $$result[0]->{'runtime.connectionState'}->val) == 0); my $create_time = Date::Parse::str2time($$result[0]->{'runtime.bootTime'}); if (!defined($create_time)) { - $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't Parse date '" . $$result[0]->{'runtime.bootTime'} . "'.\n"); return ; } diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index b0c092ce3..22d2c8ba7 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -264,6 +264,19 @@ sub vm_state { return 1; } +sub host_state { + my ($obj_esxd, $host, $connection_state) = @_; + + if ($connection_state !~ /^connected$/i) { + my $output = "Host '" . $host . "' not connected. Current Connection State: '$connection_state'."; + my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{host_state_error}); + $obj_esxd->print_response(get_status($status) . "|$output\n"); + return 0; + } + + return 1; +} + sub stats_info { my ($obj_esxd, $rh, $current_fileno, $args) = @_; my $output; From e6303ecc4faf4072e424dac77bcfccae2ad0ef8c Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 2 Jul 2013 09:55:19 +0000 Subject: [PATCH 043/447] Ref #4877 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@61 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 55 +++++++++-- connectors/vmware/centreonesxd.pm | 1 + .../vmware/lib/cmdthinprovisioningvm.pm | 96 +++++++++++++++++++ connectors/vmware/lib/common.pm | 4 +- 4 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 connectors/vmware/lib/cmdthinprovisioningvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 1a3179636..3bfb674da 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.3"; +my $VERSION = "1.4"; my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3, 'DEPENDENT' => 4); my $socket; @@ -24,7 +24,8 @@ my %OPTION = ( "datastore" => undef, "nic" => undef, "warning" => undef, - "critical" => undef + "critical" => undef, + "on" => undef, ); Getopt::Long::Configure('bundling'); @@ -48,6 +49,8 @@ GetOptions( "older=i" => \$OPTION{'older'}, "warn" => \$OPTION{'warn'}, "crit" => \$OPTION{'crit'}, + + "on" => \$OPTION{'on'}, "w|warning=i" => \$OPTION{'warning'}, "c|critical=i" => \$OPTION{'critical'}, @@ -161,6 +164,12 @@ sub print_usage () { print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; print "\n"; + print "'thinprovisioningvm':\n"; + print " --vm VM to check (required)\n"; + print " --on Warn or critical if thinprovisioning set\n"; + print " --crit Critical\n"; + print " --warn Warn\n"; + print "\n"; print "'listhost':\n"; print " None\n"; print "\n"; @@ -180,7 +189,7 @@ sub print_usage () { sub print_help () { print "##############################################\n"; - print "# Copyright (c) 2005-2012 Centreon #\n"; + print "# Copyright (c) 2005-2013 Centreon #\n"; print "# Bugs to http://redmine.merethis.net/ #\n"; print "##############################################\n"; print "\n"; @@ -482,11 +491,11 @@ sub snapshotvm_get_str { } sub datastoresvm_check_arg { - if (!defined($OPTION{'vm'})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{'UNKNOWN'}; - } + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } if (!defined($OPTION{'warning'})) { $OPTION{'warning'} = ''; } @@ -538,6 +547,34 @@ sub swapvm_get_str { return "swapvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub thinprovisioningvm_check_arg { + if (!defined($OPTION{'vm'})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'on'})) { + $OPTION{'on'} = 0; + } else { + $OPTION{'on'} = 1; + } + if (!defined($OPTION{'warn'})) { + $OPTION{'warn'} = 0; + } else { + $OPTION{'warn'} = 1; + } + if (!defined($OPTION{'crit'})) { + $OPTION{'crit'} = 0; + } else { + $OPTION{'crit'} = 1; + } + return 0; +} + +sub thinprovisioningvm_get_str { + return "thinprovisioningvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'on'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; +} + sub listhost_check_arg { return 0; @@ -607,7 +644,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 7b5a15d04..995612415 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -41,6 +41,7 @@ my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdstatushost', 'centreon::esxd::cmdswaphost', 'centreon::esxd::cmdswapvm', + 'centreon::esxd::cmdthinprovisioningvm', 'centreon::esxd::cmdtoolsvm', 'centreon::esxd::cmduptimehost' ); diff --git a/connectors/vmware/lib/cmdthinprovisioningvm.pm b/connectors/vmware/lib/cmdthinprovisioningvm.pm new file mode 100644 index 000000000..9cca1e71b --- /dev/null +++ b/connectors/vmware/lib/cmdthinprovisioningvm.pm @@ -0,0 +1,96 @@ + +package centreon::esxd::cmdthinprovisioningvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'thinprovisioningvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm, $warn, $crit) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm name"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{on} = ((defined($_[1]) and $_[1] ne '') ? $_[1] : 0); + $self->{warn} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); + $self->{crit} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); +} + +sub run { + my $self = shift; + + my %filters = ('name' => $self->{lvm}); + my @properties = ('config.hardware.device', 'runtime.connectionState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, + $$result[0]->{'runtime.connectionState'}->val, + undef, 1) == 0); + + my $status = 0; + my $output = ""; + my $output_append = ''; + foreach (@{$$result[0]->{'config.hardware.device'}}) { + if ($_->isa('VirtualDisk')) { + if ($self->{on} == 1 && $self->{warn} == 1 && $_->backing->thinProvisioned == 1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + centreon::esxd::common::output_add(\$output, \$output_append, ", ", + "'" . $_->backing->fileName . "'"); + } + if ($self->{on} == 1 && $self->{crit} == 1 && $_->backing->thinProvisioned == 1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + centreon::esxd::common::output_add(\$output, \$output_append, ", ", + "'" . $_->backing->fileName . "'"); + } + if ($self->{on} == 0 && $self->{warn} == 1 && $_->backing->thinProvisioned != 1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + centreon::esxd::common::output_add(\$output, \$output_append, ", ", + "'" . $_->backing->fileName . "'"); + } + if ($self->{on} == 0 && $self->{crit} == 1 && $_->backing->thinProvisioned != 1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + centreon::esxd::common::output_add(\$output, \$output_append, ", ", + "'" . $_->backing->fileName . "'"); + } + } + } + + if ($output ne "" && $self->{on} == 1) { + $output = "VirtualDisks $output: thinprovisioning actived."; + } elsif ($output ne "" && $self->{on} == 0) { + $output = "VirtualDisks $output: thinprovisioning not actived."; + } else { + $output = "Thinprovisoning virtualdisks are ok."; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 22d2c8ba7..f36f9137a 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -245,7 +245,7 @@ sub datastore_state { } sub vm_state { - my ($obj_esxd, $vm, $connection_state, $power_state) = @_; + my ($obj_esxd, $vm, $connection_state, $power_state, $nocheck_ps) = @_; if ($connection_state !~ /^connected$/i) { my $output = "VM '" . $vm . "' not connected. Current Connection State: '$connection_state'."; @@ -254,7 +254,7 @@ sub vm_state { return 0; } - if ($power_state !~ /^poweredOn$/i) { + if (!defined($nocheck_ps) && $power_state !~ /^poweredOn$/i) { my $output = "VM '" . $vm . "' not running. Current Power State: '$power_state'."; my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error}); $obj_esxd->print_response(get_status($status) . "|$output\n"); From a7db928bea144334e5d5501a98e3a7cc311f096f Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 2 Jul 2013 13:35:14 +0000 Subject: [PATCH 044/447] Ref #5496 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@62 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 40 +++++- connectors/vmware/centreonesxd.pm | 1 + .../vmware/lib/cmddatastoresnapshots.pm | 136 ++++++++++++++++++ connectors/vmware/lib/common.pm | 43 ++++++ 4 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 connectors/vmware/lib/cmddatastoresnapshots.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 3bfb674da..ff13233b2 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -54,6 +54,9 @@ GetOptions( "w|warning=i" => \$OPTION{'warning'}, "c|critical=i" => \$OPTION{'critical'}, + + "warning2=i" => \$OPTION{'warning2'}, + "critical2=i" => \$OPTION{'critical2'}, ); if (defined($OPTION{'version'})) { @@ -99,6 +102,13 @@ sub print_usage () { print " -w (--warning) Warning Threshold in kBps (default none)\n"; print " -c (--critical) Critical Threshold in kBps (default none)\n"; print "\n"; + print "'datastore-snapshots':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; + print " -c (--critical) Critical Threshold in bytes for all snapshots (default none)\n"; + print " --warning2 Warning Threshold in bytes for one snapshot (default none)\n"; + print " --critical2 Critical Threshold in bytes for one snapshot (default none)\n"; + print "\n"; print "'cpuhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; @@ -294,6 +304,32 @@ sub datastoreio_get_str { return "datastore-io|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; } +sub datastoresnapshots_check_arg { + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{'UNKNOWN'}; + } + if (!defined($OPTION{'warning'})) { + $OPTION{'warning'} = ''; + } + if (!defined($OPTION{'critical'})) { + $OPTION{'critical'} = ''; + } + if (!defined($OPTION{'warning2'})) { + $OPTION{'warning2'} = ''; + } + if (!defined($OPTION{'critical2'})) { + $OPTION{'critical2'} = ''; + } + return 0; +} + +sub datastoresnapshots_get_str { + return "datastore-snapshots|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} + . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'warning2'} . "|" . $OPTION{'critical2'}; +} + sub cpuhost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; @@ -335,7 +371,7 @@ sub datastoreshost_check_arg { } sub datastoreshost_get_str { - return "datastoreshost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'filter-datastores'}; + return "datastoreshost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'filter-datastores'}; } sub memhost_check_arg { @@ -644,7 +680,7 @@ if (!defined($OPTION{'usage'})) { print_usage(); exit $ERRORS{'UNKNOWN'}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 995612415..b83ca05f3 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -26,6 +26,7 @@ my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuvm', 'centreon::esxd::cmddatastoreio', 'centreon::esxd::cmddatastoreshost', + 'centreon::esxd::cmddatastoresnapshots', 'centreon::esxd::cmddatastoresvm', 'centreon::esxd::cmddatastoreusage', 'centreon::esxd::cmdgetmap', diff --git a/connectors/vmware/lib/cmddatastoresnapshots.pm b/connectors/vmware/lib/cmddatastoresnapshots.pm new file mode 100644 index 000000000..3b51c3108 --- /dev/null +++ b/connectors/vmware/lib/cmddatastoresnapshots.pm @@ -0,0 +1,136 @@ + +package centreon::esxd::cmddatastoresnapshots; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'datastore-snapshots'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($ds, $warn, $crit, $warn2, $crit2) = @_; + + if (!defined($ds) || $ds eq "") { + $self->{logger}->writeLogError("ARGS error: need datastore name"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + if (defined($warn2) && $warn2 ne "" && $warn2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn2 threshold must be a positive number"); + return 1; + } + if (defined($crit2) && $crit2 ne "" && $crit2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit2 threshold must be a positive number"); + return 1; + } + if (defined($warn2) && defined($crit2) && $warn2 ne "" && $crit2 ne "" && $warn2 > $crit2) { + $self->{logger}->writeLogError("ARGS error: warn2 threshold must be lower than crit2 threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{ds} = $_[0]; + $self->{warn} = (defined($_[1]) ? $_[1] : ''); + $self->{crit} = (defined($_[2]) ? $_[2] : ''); + $self->{warn2} = (defined($_[3]) ? $_[3] : ''); + $self->{crit2} = (defined($_[4]) ? $_[4] : ''); +} + +sub run { + my $self = shift; + + my %filters = ('summary.name' => $self->{ds}); + my @properties = ('summary.accessible', 'browser'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->{'summary.accessible'}) == 0); + + @properties = (); + my $browse_ds; + return if (!($browse_ds = centreon::esxd::common::get_view($self->{obj_esxd}, $$result[0]->{'browser'}, \@properties))); + + my $snapshots; + return if (!($snapshots = centreon::esxd::common::search_in_datastore($self->{obj_esxd}, $browse_ds, '[' . $self->{ds} . ']', [VmSnapshotFileQuery->new()]))); + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ""; + my $output_warning_append = ''; + my $output_critical = ""; + my $output_critical_append = ''; + my $total_size = 0; + + foreach (@$snapshots) { + if (defined($_->file)) { + foreach my $x (@{$_->file}) { + if (defined($self->{crit2}) && $self->{crit2} ne '' && $x->fileSize >= $self->{crit2}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "'" . $_->folderPath . ' => ' . $x->path . "'"); + } elsif (defined($self->{warn2}) && $self->{warn2} ne '' && $x->fileSize >= $self->{warn2}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "'" . $_->folderPath . ' => ' . $x->path . "'"); + } + $total_size += $x->fileSize; + } + } + } + + if ($output_critical ne '') { + $output .= "CRITICAL - Snapshot size exceed limit: $output_critical."; + $output_append = " "; + } + if ($output_warning ne '') { + $output .= $output_append . "WARNING - Snapshot size exceed limit: $output_warning."; + $output_append = " "; + } + + if (defined($self->{crit}) && $self->{crit} && $total_size >= $self->{crit}) { + $output .= $output_append . "CRITICAL - Total snapshots size exceed limit: " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB."; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} && $total_size >= $self->{warn}) { + $output .= $output_append . "WARNING - Total snapshots size exceed limit: " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB."; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } else { + $output .= $output_append . "OK - Total snapshots size is ok."; + } + $output .= "|total_size=" . $total_size . "o;$self->{warn};$self->{crit};0;"; + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index f36f9137a..b8ac42ed3 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -95,6 +95,49 @@ sub get_views { return $results; } +sub get_view { + my $obj_esxd = shift; + my $results; + + eval { + $results = $obj_esxd->{session1}->get_view(mo_ref => $_[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 search_in_datastore { + my $obj_esxd = shift; + my ($ds_browse, $ds_name, $query) = @_; + my $result; + + my $files = FileQueryFlags->new(fileSize => 1, + fileType => 1, + modification => 1, + fileOwner => 1 + ); + my $hostdb_search_spec = HostDatastoreBrowserSearchSpec->new(details => $files, + query => $query); + eval { + $result = $ds_browse->SearchDatastoreSubFolders(datastorePath=> $ds_name, + searchSpec=>$hostdb_search_spec); + }; + if ($@) { + $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@"); + my $lerror = $@; + $lerror =~ s/\n/ /g; + $obj_esxd->print_response("-1|Error: " . $lerror . "\n"); + return undef; + } + return $result; +} + sub get_perf_metric_ids { my $obj_esxd = shift; my $perf_names = $_[0]; From 03c41987a7ef49e1b3bc4383f44eb4cfe52b46af Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 2 Jul 2013 14:31:02 +0000 Subject: [PATCH 045/447] Update doc git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@63 a5eaa968-4c79-4d68-970d-af6011b5b055 --- .../vmware/doc-en/exploitation/index.rst | 38 ++---- .../vmware/doc-en/installation/index.rst | 113 +++-------------- connectors/vmware/doc/exploitation/index.rst | 39 ++---- connectors/vmware/doc/installation/index.rst | 117 +++--------------- 4 files changed, 51 insertions(+), 256 deletions(-) diff --git a/connectors/vmware/doc-en/exploitation/index.rst b/connectors/vmware/doc-en/exploitation/index.rst index 34cbfba2f..d3b1d098b 100644 --- a/connectors/vmware/doc-en/exploitation/index.rst +++ b/connectors/vmware/doc-en/exploitation/index.rst @@ -28,8 +28,7 @@ Steps of operation : Then, this process gets back the VMWare indicators creating a subprocess per request. -Centreon-esxd necessitates the utilization of one (or more) VirtualCenter. It isn't possible to get back informations of an ESX server directly. - +Centreon-esxd necessitates the utilization of one (or more) VirtualCenter (or ESX). This is a example of a fragmented architecture : .. image:: ../images/archi.png @@ -44,35 +43,18 @@ Configuration du connecteur ``````````````````````````` Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - 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'} - 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"; + } + port => 5700 + }; -La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. - -La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». - -Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. - -Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. +L'attribut «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. +L'attribut « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». Optimisation de la configuration dans Centreon ---------------------------------------------- diff --git a/connectors/vmware/doc-en/installation/index.rst b/connectors/vmware/doc-en/installation/index.rst index fd8b2f207..9fae9d636 100644 --- a/connectors/vmware/doc-en/installation/index.rst +++ b/connectors/vmware/doc-en/installation/index.rst @@ -14,9 +14,10 @@ Installation on other system is possible but is outside the scope of this docume ==================== ===================== Software Minimal Version ==================== ===================== -VMWare SDK Perl 5.0 -Perl 5.8 -centreon-esxd 1.3 +VMWare SDK Perl 5.1 +Perl 5.8 +centreon-esxd 1.4 +centreon-common-perl 2.5 ==================== ===================== Hardware Recommandations @@ -36,16 +37,12 @@ SDK Perl VMWare Installation The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. - Install CPAN prerequisites :: - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay + root # yum install gcc make unzip wget e2fsprogs-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-libwww-perl perl-TimeDate root # cpan install Class::MethodMaker - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https root # cpan install SOAP::Lite root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz @@ -60,44 +57,33 @@ Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) - -Install VMWare Perl SDK:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install - -Addtionnal Modules Installation -``````````````````````````````` - -Some features require additionnal prerequisites. - -To send data to a syslog daemon, the " Unix::Syslog" must be installed :: - - root # cpan install Unix::Syslog - -To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Reboot your system to complete. - -centreon-esxd Installation -`````````````````````````` - -Download « centreon-esxd » archive, then install :: - - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ - -Configure "centreon-esxd" daemon to start at boot :: - - root # chkconfig --level 2345 centreon_esxd on - - -*"centreon_esx_client.pl" is the corresponding nagios plugin.* - +TODO \ No newline at end of file diff --git a/connectors/vmware/doc/exploitation/index.rst b/connectors/vmware/doc/exploitation/index.rst index c5657eb15..67bd6edf3 100644 --- a/connectors/vmware/doc/exploitation/index.rst +++ b/connectors/vmware/doc/exploitation/index.rst @@ -28,7 +28,7 @@ Voici le fonctionnement : Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. -Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. +Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter (ou ESX). Voici un exemple d'architecture éclaté : @@ -38,41 +38,24 @@ Mode de fonctionnement `````````````````````` Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). -Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. +Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. Configuration du connecteur ``````````````````````````` Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - 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'} - 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"; + } + port => 5700 + }; -La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. - -La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». - -Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. - -Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. +L'attribut «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. +L'attribut « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». Optimisation de la configuration dans Centreon ---------------------------------------------- diff --git a/connectors/vmware/doc/installation/index.rst b/connectors/vmware/doc/installation/index.rst index 3534d2c3c..547c0120a 100644 --- a/connectors/vmware/doc/installation/index.rst +++ b/connectors/vmware/doc/installation/index.rst @@ -14,9 +14,10 @@ L'installation sur d'autres environnements n'est pas exclu mais non présenté d ==================== ===================== Logiciels Version minimum ==================== ===================== -VMWare SDK Perl 5.0 -Perl 5.8 -centreon-esxd 1.3 +VMWare SDK Perl 5.1 +Perl 5.8 +centreon-esxd 1.4 +centreon-common-perl 2.5 ==================== ===================== Préconisations matérielles @@ -36,16 +37,12 @@ Installation du SDK Perl VMWare Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. - Installer les pré-requis CPAN:: - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay + root # yum install gcc make unzip wget e2fsprogs-devel + root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-libwww-perl perl-TimeDate root # cpan install Class::MethodMaker - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https root # cpan install SOAP::Lite root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz @@ -60,28 +57,15 @@ Télécharger la dernière version, correspondant à votre architecture 32/64 bi Installer le SDK Perl VMWare:: - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz + root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.gz root # cd vmware-vsphere-cli-distrib root # perl Makefile.pl root # make && make install -Installation de modules complémentaires +Pré-requis ``````````````````````````````````````` -Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : - -Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: - - root # cpan install Unix::Syslog - -Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Ensuite redémarrer votre système. +« centreon-common-perl » est nécessaire pour le fonctionnement de « centreon_esxd ». Ce module est présent à partir de Centreon 2.5. Installation de centreon-esxd ````````````````````````````` @@ -90,16 +74,17 @@ Télécharger l'archive de « centreon-esxd ». Installer les fichiers:: - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X + root # tar zxvf centreon-esxd-1.4.tar.gz + root # cd centreon-esxd-1.4 root # cp centreon_esxd /usr/bin/ root # mkdir -p /etc/centreon root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm root # cp centreon_esxd-init /etc/init.d/centreon_esxd - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ + root # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/ + root # cp lib/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/ + root # cp centreonesxd.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ Activer le daemon « centreon-esxd » au démarrage:: @@ -114,78 +99,6 @@ Installation de centreon-esxd - Environnement centos/rhel 6 Installation du sdk Perl VMWare ``````````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. - -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. - -Installer les pré-requis CPAN:: - - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite - - root # cpan install Test::More - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install - -Nous avons notre environnement prêt pour l'installation du SDK VMWare. - -Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_) - -Installer le SDK Perl VMWare:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install - -Installation de modules complémentaires -``````````````````````````````````````` - -Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : - -Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: - - root # cpan install Unix::Syslog - -Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Ensuite redémarrer votre système. - -Installation de centreon-esxd -````````````````````````````` - -Télécharger l'archive de « centreon-esxd ». - -Installer les fichiers:: - - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ - -Activer le daemon « centreon-esxd » au démarrage:: - - root # chkconfig --level 2345 centreon_esxd on - - -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* +TODO From 9295f468b468987636d1edf539b98995d28e4ffd Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Sun, 21 Jul 2013 19:36:01 +0000 Subject: [PATCH 046/447] Fix critical bug Manage problem better git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@65 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 4 +- connectors/vmware/centreon_esxd-conf.pm | 6 +- connectors/vmware/centreonesxd.pm | 2 +- connectors/vmware/lib/cmdcpuhost.pm | 7 +-- connectors/vmware/lib/cmdcpuvm.pm | 1 + connectors/vmware/lib/cmddatastoreio.pm | 1 + connectors/vmware/lib/cmddatastoreshost.pm | 1 + connectors/vmware/lib/cmddatastoresvm.pm | 1 + connectors/vmware/lib/cmdmemhost.pm | 1 + connectors/vmware/lib/cmdmemvm.pm | 1 + connectors/vmware/lib/cmdnethost.pm | 1 + connectors/vmware/lib/cmdswaphost.pm | 1 + connectors/vmware/lib/cmdswapvm.pm | 1 + connectors/vmware/lib/common.pm | 65 ++++++++++++++-------- 14 files changed, 61 insertions(+), 32 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index ff13233b2..ef158e542 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.4"; +my $VERSION = "1.4.1"; my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3, 'DEPENDENT' => 4); my $socket; @@ -702,7 +702,7 @@ my $status_return = $1; $return =~ s/^(-?[0-9]*?)\|//; print $return . "\n"; -if ($status_return == -1) { +if ($status_return < 0) { $status_return = 3; } exit $status_return; diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/centreon_esxd-conf.pm index f8c0d57da..a6bd08e1f 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/centreon_esxd-conf.pm @@ -1,10 +1,10 @@ -$centreonesxd_config = { +%centreonesxd_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', - 'username' => 'qgarnier@merethis.net', + 'username' => 'XXXXXX', 'password' => 'XXXXXX'} } -}; +); 1; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index b83ca05f3..3734575e1 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -517,7 +517,7 @@ sub run { } my @results = split(/\|/, $data_element); my ($id, $counter) = split(/\./, $results[0]); - if (!defined($self->{sockets}->{$id}) || $self->{counter} != $self->{sockets}->{$id}->{'counter'}) { + if (!defined($self->{sockets}->{$id}) || $counter != $self->{sockets}->{$id}->{'counter'}) { $self->{logger}->writeLogInfo("Too much time to get response."); next; } diff --git a/connectors/vmware/lib/cmdcpuhost.pm b/connectors/vmware/lib/cmdcpuhost.pm index 01e4f1a07..58ad1e215 100644 --- a/connectors/vmware/lib/cmdcpuhost.pm +++ b/connectors/vmware/lib/cmdcpuhost.pm @@ -64,9 +64,7 @@ sub run { my %filters = ('name' => $self->{lhost}); my @properties = ('name', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, $$result[0]->{'runtime.connectionState'}->val) == 0); @@ -77,7 +75,8 @@ sub run { $$result[0], [{'label' => 'cpu.usage.average', 'instances' => \@instances}], $self->{obj_esxd}->{perfcounter_speriod}); - + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + my $status = 0; # OK my $output = ''; my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); diff --git a/connectors/vmware/lib/cmdcpuvm.pm b/connectors/vmware/lib/cmdcpuvm.pm index 85b79904f..e5ac7278c 100644 --- a/connectors/vmware/lib/cmdcpuvm.pm +++ b/connectors/vmware/lib/cmdcpuvm.pm @@ -78,6 +78,7 @@ sub run { [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $status = 0; # OK my $output = ''; diff --git a/connectors/vmware/lib/cmddatastoreio.pm b/connectors/vmware/lib/cmddatastoreio.pm index d4563b806..e610d50a0 100644 --- a/connectors/vmware/lib/cmddatastoreio.pm +++ b/connectors/vmware/lib/cmddatastoreio.pm @@ -74,6 +74,7 @@ sub run { [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])); my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])); diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index 0240623a9..0191e3385 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -100,6 +100,7 @@ sub run { [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $status = 0; # OK my $output = ''; diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/lib/cmddatastoresvm.pm index 549b6ebb7..c499cee3e 100644 --- a/connectors/vmware/lib/cmddatastoresvm.pm +++ b/connectors/vmware/lib/cmddatastoresvm.pm @@ -108,6 +108,7 @@ sub run { [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); foreach (keys %$values) { my ($id, $disk_name) = split(/:/); diff --git a/connectors/vmware/lib/cmdmemhost.pm b/connectors/vmware/lib/cmdmemhost.pm index 975736bb3..b7d90e824 100644 --- a/connectors/vmware/lib/cmdmemhost.pm +++ b/connectors/vmware/lib/cmdmemhost.pm @@ -77,6 +77,7 @@ sub run { [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])); my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])); diff --git a/connectors/vmware/lib/cmdmemvm.pm b/connectors/vmware/lib/cmdmemvm.pm index 801abbcc1..25d32c288 100644 --- a/connectors/vmware/lib/cmdmemvm.pm +++ b/connectors/vmware/lib/cmdmemvm.pm @@ -81,6 +81,7 @@ sub run { {'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.shared.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])); my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])); diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index e3a996259..7c1a80af1 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -94,6 +94,7 @@ sub run { [{'label' => 'net.received.average', 'instances' => [$self->{pnic}]}, {'label' => 'net.transmitted.average', 'instances' => [$self->{pnic}]}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{'key'} . ":" . $self->{pnic}}[0])); my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{'key'} . ":" . $self->{pnic}}[0])); diff --git a/connectors/vmware/lib/cmdswaphost.pm b/connectors/vmware/lib/cmdswaphost.pm index 15d6b7812..8384896e8 100644 --- a/connectors/vmware/lib/cmdswaphost.pm +++ b/connectors/vmware/lib/cmdswaphost.pm @@ -75,6 +75,7 @@ sub run { [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])); my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); diff --git a/connectors/vmware/lib/cmdswapvm.pm b/connectors/vmware/lib/cmdswapvm.pm index 4db072210..7c52a1e84 100644 --- a/connectors/vmware/lib/cmdswapvm.pm +++ b/connectors/vmware/lib/cmdswapvm.pm @@ -76,6 +76,7 @@ sub run { [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])); my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index b8ac42ed3..95c8e5e1e 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -32,6 +32,19 @@ sub response_client1 { close $rh; } +sub vmware_error { + my ($obj_esxd, $lerror) = @_; + + $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $lerror"); + $lerror =~ s/\n/ /g; + if ($lerror =~ /NoPermissionFault/i) { + $obj_esxd->print_response("-2|Error: Not enough permissions\n"); + } else { + $obj_esxd->print_response("-1|Error: " . $lerror . "\n"); + } + return undef; +} + sub connect_vsphere { my ($logger, $whoaim, $timeout_vsphere, $session1, $service_url, $username, $password) = @_; $logger->writeLogInfo("'$whoaim' Vsphere connection in progress"); @@ -86,10 +99,7 @@ sub get_views { $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"); + vmware_error($obj_esxd, $@); return undef; } return $results; @@ -103,10 +113,7 @@ sub get_view { $results = $obj_esxd->{session1}->get_view(mo_ref => $_[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"); + vmware_error($obj_esxd, $@); return undef; } return $results; @@ -129,10 +136,7 @@ sub search_in_datastore { searchSpec=>$hostdb_search_spec); }; if ($@) { - $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@"); - my $lerror = $@; - $lerror =~ s/\n/ /g; - $obj_esxd->print_response("-1|Error: " . $lerror . "\n"); + vmware_error($obj_esxd, $@); return undef; } return $result; @@ -141,20 +145,22 @@ sub search_in_datastore { sub get_perf_metric_ids { my $obj_esxd = shift; my $perf_names = $_[0]; - my @filtered_list; + 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; + push @$filtered_list, $metric; } } else { $obj_esxd->{logger}->writeLogError("Metric '" . $_->{'label'} . "' unavailable."); + $obj_esxd->print_response("-3|Error: Counter doesn't exist. VMware version can be too old.\n"); + return undef; } } - return \@filtered_list; + return $filtered_list; } sub generic_performance_values_historic { @@ -163,7 +169,8 @@ sub generic_performance_values_historic { my %results; eval { - my @perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); + my $perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); + return undef if (!defined($perf_metric_ids)); my $perf_query_spec; my $tstamp = time(); @@ -174,9 +181,10 @@ sub generic_performance_values_historic { my $endTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + # $obj_esxd->{logger}->writeLogError(@perf_metric_ids); if ($interval == 20) { $perf_query_spec = PerfQuerySpec->new(entity => $view, - metricId => @perf_metric_ids, + metricId => $perf_metric_ids, format => 'normal', intervalId => 20, startTime => $startTime, @@ -184,7 +192,7 @@ sub generic_performance_values_historic { maxSample => 1); } else { $perf_query_spec = PerfQuerySpec->new(entity => $view, - metricId => @perf_metric_ids, + metricId => $perf_metric_ids, format => 'normal', intervalId => $interval, startTime => $startTime, @@ -193,8 +201,16 @@ sub generic_performance_values_historic { #maxSample => 1); } my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => $perf_query_spec); + if (!$$perfdata[0]) { + $obj_esxd->print_response("-3|Error: Cannot get value for couters. Maybe there is time sync problem (check the esxd server and the target also).\n"); + return undef; + } foreach (@{$$perfdata[0]->value}) { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + if (!defined($_->value)) { + $obj_esxd->print_response("-3|Error: Cannot get value for couters. Maybe there is time sync problem (check the esxd server and the target also).\n"); + return undef; + } } }; if ($@) { @@ -248,10 +264,7 @@ sub get_entities_host { $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"); + vmware_error($obj_esxd, $@); return undef; } } @@ -274,6 +287,14 @@ sub get_entities_host { return $entity_views; } +sub performance_errors { + my ($obj_esxd, $values) = @_; + + # Error counter not available or orther from function + return 1 if (!defined($values) || scalar(keys(%$values)) <= 0); + return 0; +} + sub datastore_state { my ($obj_esxd, $ds, $accessible) = @_; From bd095d1633707d695627a2a7bece599241b39680 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 23 Jul 2013 08:31:41 +0000 Subject: [PATCH 047/447] Add option in init script git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@68 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd-init | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/centreon_esxd-init b/connectors/vmware/centreon_esxd-init index f20828402..35f1333db 100644 --- a/connectors/vmware/centreon_esxd-init +++ b/connectors/vmware/centreon_esxd-init @@ -13,6 +13,7 @@ binary=/usr/bin/centreon_esxd servicename=$(basename "$0") +options="" user=root timeout=60 @@ -45,9 +46,9 @@ start() { fi if [ "$(id -u -n)" = "$user" ] ; then - daemon ''$binary' "'$config_file'" > /dev/null 2>&1 &' + daemon ''$binary' '$options' > /dev/null 2>&1 &' else - daemon --user $user ''$binary' "'$config_file'" > /dev/null 2>&1 &' + daemon --user $user ''$binary' '$options' > /dev/null 2>&1 &' fi pid=$(pidofproc $binary) RETVAL=$? From 6410eb0429800620fe114f2e4203dc0de87417e7 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 9 Sep 2013 13:40:54 +0000 Subject: [PATCH 048/447] + Add sysconfig file git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@69 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd-init | 8 +++++--- connectors/vmware/centreon_esxd-sysconfig | 2 ++ connectors/vmware/lib/common.pm | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 connectors/vmware/centreon_esxd-sysconfig diff --git a/connectors/vmware/centreon_esxd-init b/connectors/vmware/centreon_esxd-init index 35f1333db..501485599 100644 --- a/connectors/vmware/centreon_esxd-init +++ b/connectors/vmware/centreon_esxd-init @@ -13,12 +13,14 @@ binary=/usr/bin/centreon_esxd servicename=$(basename "$0") -options="" +OPTIONS="" user=root timeout=60 pidfile=/var/run/centreon_esxd.pid +[ -e /etc/sysconfig/$servicename ] && . /etc/sysconfig/$servicename + # Check if we can find the binary. if [ ! -x $binary ]; then echo -n $"Starting $servicename."; @@ -46,9 +48,9 @@ start() { fi if [ "$(id -u -n)" = "$user" ] ; then - daemon ''$binary' '$options' > /dev/null 2>&1 &' + daemon ''$binary' '$OPTIONS' > /dev/null 2>&1 &' else - daemon --user $user ''$binary' '$options' > /dev/null 2>&1 &' + daemon --user $user ''$binary' '$OPTIONS' > /dev/null 2>&1 &' fi pid=$(pidofproc $binary) RETVAL=$? diff --git a/connectors/vmware/centreon_esxd-sysconfig b/connectors/vmware/centreon_esxd-sysconfig new file mode 100644 index 000000000..ca1a0880e --- /dev/null +++ b/connectors/vmware/centreon_esxd-sysconfig @@ -0,0 +1,2 @@ +# centreon_esxd command line options +OPTIONS="--logfile=/var/log/centreon/centreon_esxd.log --severity=error" \ No newline at end of file diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 95c8e5e1e..4130db8fa 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -181,7 +181,6 @@ sub generic_performance_values_historic { my $endTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); - # $obj_esxd->{logger}->writeLogError(@perf_metric_ids); if ($interval == 20) { $perf_query_spec = PerfQuerySpec->new(entity => $view, metricId => $perf_metric_ids, From 81933cfa69c24a70e2976bcc107364911ead528f Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 08:36:58 +0000 Subject: [PATCH 049/447] Fix config extra option git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@70 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreonesxd.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 3734575e1..4b232d89f 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -57,7 +57,7 @@ sub new { bless $self, $class; $self->add_options( - "config-extra" => \$self->{opt_extra}, + "config-extra=s" => \$self->{opt_extra}, ); %{$self->{centreonesxd_default_config}} = From 3929e91a7c64f33f2a14d314816a0f35863f78f6 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 11:29:51 +0000 Subject: [PATCH 050/447] Use a new separator ('~' by default). (permits to use regexp for filters) git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@71 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 319 ++++++++++++----------- connectors/vmware/centreonesxd.pm | 93 +++---- 2 files changed, 219 insertions(+), 193 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index ef158e542..576ba60e2 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,9 +6,10 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.4.1"; -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3, 'DEPENDENT' => 4); +my $VERSION = "1.5.0"; +my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); my $socket; +my $separatorin = '~'; sub print_help(); sub print_usage(); @@ -59,14 +60,14 @@ GetOptions( "critical2=i" => \$OPTION{'critical2'}, ); -if (defined($OPTION{'version'})) { +if (defined($OPTION{version})) { print_revision($PROGNAME, $VERSION); - exit $ERRORS{'OK'}; + exit $ERRORS{OK}; } -if (defined($OPTION{'help'})) { +if (defined($OPTION{help})) { print_help(); - exit $ERRORS{'OK'}; + exit $ERRORS{OK}; } ############# @@ -218,7 +219,7 @@ sub myconnect { PeerAddr => $OPTION{'esxd-host'}, PeerPort => $OPTION{'esxd-port'}))) { print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } $socket->autoflush(1); } @@ -231,116 +232,121 @@ sub maintenancehost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } return 0; } sub maintenancehost_get_str { - return "maintenancehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return join($separatorin, + ('maintenancehost', $OPTION{vsphere}, $OPTION{'esx-host'})); } sub statushost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } return 0; } sub statushost_get_str { - return "statushost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return join($separatorin, + ('statushost', $OPTION{vsphere}, $OPTION{'esx-host'})); } sub healthhost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } return 0; } sub healthhost_get_str { - return "healthhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return join($separatorin, + ('healthhost', $OPTION{vsphere}, $OPTION{'esx-host'})); } sub datastoreusage_check_arg { - if (!defined($OPTION{'datastore'})) { + if (!defined($OPTION{datastore})) { print "Option --datastore is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; } return 0; } sub datastoreusage_get_str { - return "datastore-usage|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical})); } sub datastoreio_check_arg { if (!defined($OPTION{'datastore'})) { print "Option --datastore is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; } return 0; } sub datastoreio_get_str { - return "datastore-io|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('datastore-io', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical})); } sub datastoresnapshots_check_arg { - if (!defined($OPTION{'datastore'})) { + if (!defined($OPTION{datastore})) { print "Option --datastore is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; } - if (!defined($OPTION{'warning2'})) { - $OPTION{'warning2'} = ''; + if (!defined($OPTION{warning2})) { + $OPTION{warning2} = ''; } - if (!defined($OPTION{'critical2'})) { - $OPTION{'critical2'} = ''; + if (!defined($OPTION{critical2})) { + $OPTION{critical2} = ''; } return 0; } sub datastoresnapshots_get_str { - return "datastore-snapshots|" . $OPTION{'vsphere'} . "|" . $OPTION{'datastore'} - . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'warning2'} . "|" . $OPTION{'critical2'}; + return join($separatorin, + ('datastore-snapshots', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); } sub cpuhost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; } if (!defined($OPTION{'light-perfdata'})) { $OPTION{'light-perfdata'} = 0; @@ -349,20 +355,21 @@ sub cpuhost_check_arg { } sub cpuhost_get_str { - return "cpuhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'light-perfdata'}; + return join($separatorin, + ('cpuhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical}, $OPTION{'light-perfdata'})); } sub datastoreshost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; } if (!defined($OPTION{'filter-datastores'})) { $OPTION{'filter-datastores'} = ''; @@ -371,244 +378,257 @@ sub datastoreshost_check_arg { } sub datastoreshost_get_str { - return "datastoreshost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'} . "|" . $OPTION{'filter-datastores'}; + return join($separatorin, + ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical} , $OPTION{'filter-datastores'})); } sub memhost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; } return 0; } sub memhost_get_str { - return "memhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('memhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); } sub swaphost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 0.8; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 0.8; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 1; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 1; } return 0; } sub swaphost_get_str { - return "swaphost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('swaphost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); } sub nethost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'nic'})) { + if (!defined($OPTION{nic})) { print "Option --nic is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; } return 0; } sub nethost_get_str { - return "nethost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'nic'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{warning}, $OPTION{critical})); } sub countvmhost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; } return 0; } sub countvmhost_get_str { - return "countvmhost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('countvmhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); } sub uptimehost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } return 0; } sub uptimehost_get_str { - return "uptimehost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return join($separatorin, + ('uptimehost', $OPTION{vsphere}, $OPTION{'esx-host'})); } sub cpuvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; } return 0; } sub cpuvm_get_str { - return "cpuvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('cpuvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); } sub toolsvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } return 0; } sub toolsvm_get_str { - return "toolsvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'}; + return join($separatorin, + ('toolsvm', $OPTION{vsphere}, $OPTION{vm})); } sub snapshotvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'older'})) { - $OPTION{'older'} = ''; + if (!defined($OPTION{older})) { + $OPTION{older} = ''; } - if (!defined($OPTION{'warn'})) { - $OPTION{'warn'} = 0; + if (!defined($OPTION{warn})) { + $OPTION{warn} = 0; } else { - $OPTION{'warn'} = 1; + $OPTION{warn} = 1; } - if (!defined($OPTION{'crit'})) { - $OPTION{'crit'} = 0; + if (!defined($OPTION{crit})) { + $OPTION{crit} = 0; } else { - $OPTION{'crit'} = 1; + $OPTION{crit} = 1; } return 0; } sub snapshotvm_get_str { - return "snapshotvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'older'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; + return join($separatorin, + ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{older}, $OPTION{warn}, $OPTION{crit})); } sub datastoresvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ''; + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ''; + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; } return 0; } sub datastoresvm_get_str { - return "datastoresvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('datastoresvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); } sub memvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 80; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 90; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; } return 0; } sub memvm_get_str { - return "memvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('memvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); } sub swapvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = 0.8; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 0.8; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = 1; + if (!defined($OPTION{critical})) { + $OPTION{critical} = 1; } return 0; } sub swapvm_get_str { - return "swapvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('swapvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); } sub thinprovisioningvm_check_arg { - if (!defined($OPTION{'vm'})) { + if (!defined($OPTION{vm})) { print "Option --vm is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{'on'})) { - $OPTION{'on'} = 0; + if (!defined($OPTION{on})) { + $OPTION{on} = 0; } else { - $OPTION{'on'} = 1; + $OPTION{on} = 1; } - if (!defined($OPTION{'warn'})) { - $OPTION{'warn'} = 0; + if (!defined($OPTION{warn})) { + $OPTION{warn} = 0; } else { - $OPTION{'warn'} = 1; + $OPTION{warn} = 1; } - if (!defined($OPTION{'crit'})) { - $OPTION{'crit'} = 0; + if (!defined($OPTION{crit})) { + $OPTION{crit} = 0; } else { - $OPTION{'crit'} = 1; + $OPTION{crit} = 1; } return 0; } sub thinprovisioningvm_get_str { - return "thinprovisioningvm|" . $OPTION{'vsphere'} . "|" . $OPTION{'vm'} . "|" . $OPTION{'on'} . "|" . $OPTION{'warn'} . "|" . $OPTION{'crit'}; + return join($separatorin, + ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{on}, $OPTION{warn}, $OPTION{crit})); } @@ -617,7 +637,8 @@ sub listhost_check_arg { } sub listhost_get_str { - return "listhost|" . $OPTION{'vsphere'}; + return join($separatorin, + ('listhost', $OPTION{vsphere})); } sub listdatastore_check_arg { @@ -625,20 +646,22 @@ sub listdatastore_check_arg { } sub listdatastore_get_str { - return "listdatastore|" . $OPTION{'vsphere'}; + return join($separatorin, + ('listdatastore', $OPTION{vsphere})); } sub listnichost_check_arg { if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } return 0; } sub listnichost_get_str { - return "listnichost|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return join($separatorin, + ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'})); } sub getmap_check_arg { @@ -649,21 +672,23 @@ sub getmap_check_arg { } sub getmap_get_str { - return "getmap|" . $OPTION{'vsphere'} . "|" . $OPTION{'esx-host'}; + return join($separatorin, + ('getmap', $OPTION{vsphere}, $OPTION{'esx-host'})); } sub stats_check_arg { - if (!defined($OPTION{'warning'})) { - $OPTION{'warning'} = ""; + if (!defined($OPTION{warning})) { + $OPTION{warning} = ""; } - if (!defined($OPTION{'critical'})) { - $OPTION{'critical'} = ""; + if (!defined($OPTION{critical})) { + $OPTION{critical} = ""; } return 0; } sub stats_get_str { - return "stats||" . $OPTION{'warning'} . "|" . $OPTION{'critical'}; + return join($separatorin, + ('stats', $OPTION{warning}, $OPTION{critical})); } ################# @@ -672,18 +697,18 @@ sub stats_get_str { if (!defined($OPTION{'esxd-host'})) { print "Option -H (--esxd-host) is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } -if (!defined($OPTION{'usage'})) { +if (!defined($OPTION{usage})) { print "Option -u (--usage) is required\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } -if ($OPTION{'usage'} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); - exit $ERRORS{'UNKNOWN'}; + exit $ERRORS{UNKNOWN}; } $OPTION{'usage'} =~ s/-//g; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 4b232d89f..70ba46da2 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -20,7 +20,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); -my %handlers = ('TERM' => {}, 'HUP' => {}, 'CHLD' => {}); +my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', 'centreon::esxd::cmdcpuvm', @@ -103,10 +103,11 @@ sub new { $self->{counter} = 0; $self->{global_id} = undef; $self->{whoaim} = undef; # to know which vsphere to connect + $self->{separatorin} = '~'; $self->{filenos} = {}; $self->{module_date_parse_loaded} = 0; $self->{modules_registry} = {}; - + return $self; } @@ -214,7 +215,7 @@ sub handle_CHLD { my $child_pid; while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { - $self->{return_child}{$child_pid} = {'status' => 1, 'rtime' => time()}; + $self->{return_child}{$child_pid} = {status => 1, rtime => time()}; } $SIG{CHLD} = \&class_handle_CHLD; } @@ -239,15 +240,15 @@ sub load_module { sub verify_child { my $self = shift; my $progress = 0; - my $handle_writer_pipe = ${$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'writer_one'}}; + 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'}}; + 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'}); + kill('INT', $self->{child_proc}->{$_}->{pid}); $self->{read_select}->remove($handle); close $handle; delete $self->{child_proc}->{$_}; @@ -257,7 +258,7 @@ sub verify_child { } # Clean old hash CHILD (security) foreach (keys %{$self->{return_child}}) { - if (time() - $self->{return_child}->{$_}->{'rtime'} > 600) { + if (time() - $self->{return_child}->{$_}->{rtime} > 600) { $self->{logger}->writeLogInfo("Clean Old return_child list = " . $_); delete $self->{return_child}->{$_}; } @@ -270,9 +271,9 @@ sub vsphere_handler { my $self = shift; my $timeout_process; - my $handle_reader_pipe = ${$self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{'reader_two'}}; + 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'}}; + 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) { @@ -284,7 +285,7 @@ sub vsphere_handler { 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'}); + kill('INT', $self->{child_proc}->{$_}->{pid}); } $progress = 0; } @@ -313,9 +314,9 @@ sub vsphere_handler { $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->{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)) { @@ -372,7 +373,7 @@ sub vsphere_handler { 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()}; + $self->{child_proc}->{$id} = {ctime => time()}; my $reader; my $writer; @@ -380,15 +381,15 @@ sub vsphere_handler { $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'}) { + $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; + my ($id, $name, @args) = split /\Q$self->{separatorin}\E/, $data_element; $self->{global_id} = $id; $self->{modules_registry}->{$name}->initArgs(@args); $self->{modules_registry}->{$name}->run(); @@ -408,11 +409,11 @@ sub vsphere_handler { $output =~ s/^(.*?)\|//; my $lid = $1; if ($output =~ /^-1/) { - $self->{last_time_check} = $self->{child_proc}->{$lid}->{'ctime'}; + $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->{return_child}->{$self->{child_proc}->{$lid}->{pid}}; delete $self->{child_proc}->{$lid}; } } @@ -450,27 +451,27 @@ sub run { $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->{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'}; + 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->{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'}}); + $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]"); @@ -479,7 +480,7 @@ sub run { 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'}; + my $writer_handle = $self->{centreonesxd_config}->{vsphere_server}->{$_}->{writer_two}; print $writer_handle "STOP\n"; } $self->{stop} = 2; @@ -503,10 +504,10 @@ sub run { # 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; + $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); + $to_stop_or_not = 0 if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{running} == 1); } if ($to_stop_or_not == 1) { # We quit @@ -517,23 +518,23 @@ sub run { } my @results = split(/\|/, $data_element); my ($id, $counter) = split(/\./, $results[0]); - if (!defined($self->{sockets}->{$id}) || $counter != $self->{sockets}->{$id}->{'counter'}) { + if (!defined($self->{sockets}->{$id}) || $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"}}; + ${$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; + my ($name, $vsphere_name, @args) = split /\Q$self->{separatorin}\E/, $line; if ($name eq 'stats') { centreon::esxd::common::stats_info($self, $rh, $current_fileno, \@args); @@ -554,8 +555,8 @@ sub run { 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"; + my $tmp_handle = ${$self->{centreonesxd_config}->{vsphere_server}->{$vsphere_name}->{writer_two}}; + print $tmp_handle $current_fileno . "." . $self->{sockets}->{$current_fileno}->{counter} . $self->{separatorin} . $name . $self->{separatorin} . join($self->{separatorin}, @args) . "\n"; } else { centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Need arguments\n"); } @@ -564,11 +565,11 @@ sub run { # Verify socket foreach (keys %{$self->{sockets}}) { - if (time() - $self->{sockets}->{$_}->{'ctime'} > $self->{centreonesxd_config}->{timeout}) { + 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"}}; + ${$self->{sockets}->{$_}->{obj}}->send("3|TIMEOUT\n"); + $self->{read_select}->remove(${$self->{sockets}->{$_}->{obj}}); + close ${$self->{sockets}->{$_}->{obj}}; delete $self->{sockets}->{$_}; } } From 7edf8e502fb5c3691cd78933e431fe845d72fa2d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 13:37:47 +0000 Subject: [PATCH 051/447] Fix #5563 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@72 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 87 ++++++++----- connectors/vmware/lib/cmddatastoreusage.pm | 134 +++++++++++++++++---- connectors/vmware/lib/common.pm | 9 ++ 3 files changed, 175 insertions(+), 55 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 576ba60e2..1f3fdf59f 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -16,48 +16,53 @@ sub print_usage(); sub print_revision($$); my %OPTION = ( - "help" => undef, "version" => undef, + help => undef, version => undef, "esxd-host" => undef, "esxd-port" => 5700, - "vsphere" => '', - "usage" => undef, + vsphere => '', + usage => undef, "light-perfdata" => undef, "esx-host" => undef, - "datastore" => undef, - "nic" => undef, - "warning" => undef, - "critical" => undef, - "on" => undef, + datastore => undef, + nic => undef, + warning => undef, + critical => undef, + on => undef, + units => undef, + free => undef, + filter => undef ); Getopt::Long::Configure('bundling'); GetOptions( - "h|help" => \$OPTION{'help'}, - "V|version" => \$OPTION{'version'}, + "h|help" => \$OPTION{help}, + "V|version" => \$OPTION{version}, "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, - "vsphere=s" => \$OPTION{'vsphere'}, + "vsphere=s" => \$OPTION{vsphere}, - "u|usage=s" => \$OPTION{'usage'}, + "u|usage=s" => \$OPTION{usage}, "e|esx-host=s" => \$OPTION{'esx-host'}, - "vm=s" => \$OPTION{'vm'}, + "vm=s" => \$OPTION{vm}, - "filter-datastores=s" => \$OPTION{'filter-datastores'}, + "filter" => \$OPTION{filter}, + "free" => \$OPTION{free}, + "units=s" => \$OPTION{units}, "light-perfdata" => \$OPTION{'light-perfdata'}, - "datastore=s" => \$OPTION{'datastore'}, - "nic=s" => \$OPTION{'nic'}, + "datastore=s" => \$OPTION{datastore}, + "nic=s" => \$OPTION{nic}, - "older=i" => \$OPTION{'older'}, - "warn" => \$OPTION{'warn'}, - "crit" => \$OPTION{'crit'}, + "older=i" => \$OPTION{older}, + "warn" => \$OPTION{warn}, + "crit" => \$OPTION{crit}, - "on" => \$OPTION{'on'}, + "on" => \$OPTION{on}, - "w|warning=i" => \$OPTION{'warning'}, - "c|critical=i" => \$OPTION{'critical'}, + "w|warning=i" => \$OPTION{warning}, + "c|critical=i" => \$OPTION{critical}, - "warning2=i" => \$OPTION{'warning2'}, - "critical2=i" => \$OPTION{'critical2'}, + "warning2=i" => \$OPTION{warning2}, + "critical2=i" => \$OPTION{critical2}, ); if (defined($OPTION{version})) { @@ -95,8 +100,11 @@ sub print_usage () { print "\n"; print "'datastore-usage':\n"; print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " -w (--warning) Warning Threshold (default 80)\n"; + print " -c (--critical) Critical Threshold (default 90)\n"; + print " --units Threshold units: %, MB (default is MB)\n"; + print " --free Threshold is for free size\n"; + print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print "\n"; print "'datastore-io':\n"; print " --datastore Datastore name to check (required)\n"; @@ -272,22 +280,41 @@ sub healthhost_get_str { sub datastoreusage_check_arg { if (!defined($OPTION{datastore})) { - print "Option --datastore is required\n"; + print "Option --datastore is required.\n"; print_usage(); exit $ERRORS{UNKNOWN}; } + if (defined($OPTION{filter})) { + $OPTION{filter} = 1; + } else { + $OPTION{filter} = 0; + } + if (defined($OPTION{free})) { + $OPTION{free} = 1; + } else { + $OPTION{free} = 0; + } if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; + $OPTION{warning} = ($OPTION{free} == 1) ? 20 : 80; } if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; + $OPTION{critical} = ($OPTION{free} == 1) ? 10 : 90; + } + if (defined($OPTION{units})) { + if ($OPTION{units} ne '%' && $OPTION{units} ne 'MB') { + print "Option --units accept '%' or 'MB'.\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + } else { + $OPTION{units} = ''; } return 0; } sub datastoreusage_get_str { return join($separatorin, - ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical})); + ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units})); } sub datastoreio_check_arg { diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/lib/cmddatastoreusage.pm index e88981db3..a0f4062d2 100644 --- a/connectors/vmware/lib/cmddatastoreusage.pm +++ b/connectors/vmware/lib/cmddatastoreusage.pm @@ -23,22 +23,30 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($ds, $warn, $crit) = @_; + my ($ds, $filter, $warn, $crit, $free, $units) = @_; if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name"); + $self->{logger}->writeLogError("ARGS error: need datastore name."); return 1; } if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number."); return 1; } if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number."); return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + if (defined($warn) && defined($crit) && (!defined($free) || $free != 1) && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold."); + return 1; + } + if (defined($warn) && defined($crit) && defined($free) && $free == 1 && $warn < $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be higher than crit threshold."); + return 1; + } + if (defined($units) && ($units !~ /^(%|MB)/)) { + $self->{logger}->writeLogError("ARGS error: units should be '%' or 'MB'."); return 1; } return 0; @@ -47,14 +55,22 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{ds} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 80); - $self->{crit} = (defined($_[2]) ? $_[2] : 90); + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{free} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; + $self->{warn} = (defined($_[2]) ? $_[2] : (($self->{free} == 1) ? 20 : 80)); + $self->{crit} = (defined($_[3]) ? $_[3] : (($self->{free} == 1) ? 10 : 90)); + $self->{units} = (defined($_[5])) ? $_[5] : '%'; } sub run { my $self = shift; + my %filters = (); - my %filters = ('name' => $self->{ds}); + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{ds}\E$/; + } else { + $filters{name} = qr/$self->{ds}/; + } my @properties = ('summary'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); @@ -62,27 +78,95 @@ sub run { return ; } - return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->summary->accessible) == 0); - my $status = 0; # OK my $output = ""; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $output_ok_unit = ''; + my $perfdata = ''; + my ($warn_threshold, $crit_threshold); + my ($pctwarn_threshold, $pctcrit_threshold) = ($self->{warn}, $self->{crit}); - my $dsName = $$result[0]->summary->name; - my $capacity = $$result[0]->summary->capacity; - my $free = $$result[0]->summary->freeSpace; - my $pct = ($capacity - $free) / $capacity * 100; - - my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; - my $sizeD = $capacity / 1024 / 1024 / 1024; - - $output = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %) |used=".($capacity - $free)."o;;;0;".$capacity." size=".$capacity."o\n"; - if ($pct >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if ($self->{units} eq '%' && $self->{free} == 1) { + $pctwarn_threshold = 100 - $self->{warn}; + $pctcrit_threshold = 100 - $self->{crit}; } - if ($pct > $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + + foreach my $ds (@$result) { + if (!centreon::esxd::common::is_accessible($ds->summary->accessible)) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "'" . $ds->summary->name . "' not accessible. Can be disconnected."); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + next; + } + + my $dsName = $ds->summary->name; + my $capacity = $ds->summary->capacity; + my $free = $ds->summary->freeSpace; + + + if ($self->{units} eq 'MB' && $self->{free} == 1) { + $warn_threshold = $capacity - ($self->{warn} * 1024 * 1024); + $crit_threshold = $capacity - ($self->{crit} * 1024 * 1024); + } elsif ($self->{units} eq 'MB' && $self->{free} == 0) { + $warn_threshold = $self->{warn} * 1024 * 1024; + $crit_threshold = $self->{crit} * 1024 * 1024; + } else { + $warn_threshold = ($capacity * $pctwarn_threshold) / 100; + $crit_threshold = ($capacity * $pctcrit_threshold) / 100; + } + + my $pct = ($capacity - $free) / $capacity * 100; + + my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; + my $sizeD = $capacity / 1024 / 1024 / 1024; + + $output_ok_unit = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"; + + if ($self->{units} eq '%' && $pct >= $pctcrit_threshold) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif ($self->{units} eq '%' && $pct >= $pctwarn_threshold) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } elsif ($self->{units} eq 'MB' && ($capacity - $free) >= $crit_threshold) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif ($self->{units} eq 'MB' && ($capacity - $free) >= $warn_threshold) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + + if ($self->{filter} == 1) { + $perfdata .= " 'used_" . $dsName . "'=".($capacity - $free)."o;" . $warn_threshold . ";" . $crit_threshold . ";0;" . $capacity; + } else { + $perfdata .= " used=".($capacity - $free)."o;" . $warn_threshold . ";" . $crit_threshold . ";0;" . $capacity; + } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Datastore(s): $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Datastore(s): $output_warning"; + } + if ($status == 0) { + if ($self->{filter} == 1) { + $output = "All Datastore usages are ok"; + } else { + $output = $output_ok_unit; + } + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 4130db8fa..c7e01db9d 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -294,6 +294,15 @@ sub performance_errors { return 0; } +sub is_accessible { + my ($accessible) = @_; + + if ($accessible !~ /^true|1$/) { + return 0; + } + return 1; +} + sub datastore_state { my ($obj_esxd, $ds, $accessible) = @_; From 38307dfcca955234fcf8ef056d23d10a30243cb6 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 13:59:05 +0000 Subject: [PATCH 052/447] Add filter regexp for 'datastoreshost' command git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@73 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 17 ++++++++++++----- connectors/vmware/lib/cmddatastoreshost.pm | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 1f3fdf59f..02278188c 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -29,7 +29,7 @@ my %OPTION = ( on => undef, units => undef, free => undef, - filter => undef + filter => undef, ); Getopt::Long::Configure('bundling'); @@ -50,6 +50,7 @@ GetOptions( "units=s" => \$OPTION{units}, "light-perfdata" => \$OPTION{'light-perfdata'}, "datastore=s" => \$OPTION{datastore}, + "nic=s" => \$OPTION{nic}, "older=i" => \$OPTION{older}, @@ -144,7 +145,8 @@ sub print_usage () { print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; - print " --filter-datastores Datastores to verify (separated by coma)\n"; + print " --datastore Datastores to check (can use a regexp with --filter)\n"; + print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print "\n"; print "'countvmhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -398,15 +400,20 @@ sub datastoreshost_check_arg { if (!defined($OPTION{critical})) { $OPTION{critical} = ''; } - if (!defined($OPTION{'filter-datastores'})) { - $OPTION{'filter-datastores'} = ''; + if (!defined($OPTION{datastore})) { + $OPTION{datastore} = ''; + } + if (defined($OPTION{filter})) { + $OPTION{filter} = 1; + } else { + $OPTION{filter} = 0; } return 0; } sub datastoreshost_get_str { return join($separatorin, - ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical} , $OPTION{'filter-datastores'})); + ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical} , $OPTION{datastore}, $OPTION{filter})); } sub memhost_check_arg { diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index 0191e3385..cdfe8378a 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -50,19 +50,15 @@ sub initArgs { $self->{lhost} = $_[0]; $self->{warn} = (defined($_[1]) ? $_[1] : ''); $self->{crit} = (defined($_[2]) ? $_[2] : ''); - $self->{filter_ds} = (defined($_[3]) ? $_[3] : ''); + $self->{ds} = (defined($_[3]) ? $_[3] : ''); + $self->{filter} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; } sub run { my $self = shift; - my %valid_ds = (); my $filter_ok = 0; - if ($self->{filter_ds} ne '') { - foreach (split /,/, $self->{filter_ds}) { - $valid_ds{$_} = 1; - } - } + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); @@ -111,8 +107,12 @@ sub run { my $output_critical_append = ''; my $perfdata = ''; foreach (keys %uuid_list) { - if ($self->{filter_ds} ne '' and !defined($valid_ds{$uuid_list{$_}})) { - next; + if ($self->{ds} ne '') { + if ($self->{filter} == 0 && $uuid_list{$_} !~ /^\Q$self->{ds}\E$/) { + next; + } elsif ($self->{filter} == 1 && $uuid_list{$_} !~ /$self->{ds}/) { + next; + } } if (defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { @@ -142,9 +142,9 @@ sub run { } } - if ($self->{filter_ds} ne '' and $filter_ok == 0) { + if ($self->{ds} ne '' and $filter_ok == 0) { $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status). "|Datastore names in filter are unknown.\n"); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status). "|Can't get a datastore with the filter '$self->{ds}'.\n"); return ; } if ($output_critical ne "") { From b940582058737460372e85e17dd2c2ad8bf70477 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 14:21:44 +0000 Subject: [PATCH 053/447] Fix separator check git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@74 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreonesxd.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 70ba46da2..a87f8bca6 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -370,7 +370,7 @@ sub vsphere_handler { next; } - my ($id) = split(/\|/, $data_element); + my ($id) = split(/\Q$self->{separatorin}\E/, $data_element); if ($self->{vsphere_connected}) { $self->{logger}->writeLogInfo("vpshere '" . $self->{whoaim} . "' handler asking: $data_element"); $self->{child_proc}->{$id} = {ctime => time()}; From 5a24f1634315e67773f64631b39c9765fba0a077 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 15:07:39 +0000 Subject: [PATCH 054/447] Optimize 'datastoreshost' call git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@75 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/cmddatastoreshost.pm | 52 ++++++++++++++-------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index cdfe8378a..438d89819 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -56,7 +56,6 @@ sub initArgs { sub run { my $self = shift; - my $filter_ok = 0; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { @@ -76,25 +75,55 @@ sub run { $$result[0]->{'runtime.connectionState'}->val) == 0); my %uuid_list = (); - my %disk_name = (); + #my %disk_name = (); + my $instances = []; + if ($self->{ds} eq '') { + $instances = ['*']; + } foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { if ($_->volume->isa('HostVmfsVolume')) { + if ($self->{ds} ne '') { + if ($self->{filter} == 0 && $_->volume->name !~ /^\Q$self->{ds}\E$/) { + next; + } elsif ($self->{filter} == 1 && $_->volume->name !~ /$self->{ds}/) { + next; + } + } + + $filter_ok = 1; $uuid_list{$_->volume->uuid} = $_->volume->name; + push @$instances, $_->volume->uuid; # Not need. We are on Datastore level (not LUN level) #foreach my $extent (@{$_->volume->extent}) { # $disk_name{$extent->diskName} = $_->volume->name; #} } if ($_->volume->isa('HostNasVolume')) { + if ($self->{ds} ne '') { + if ($self->{filter} == 0 && $_->volume->name !~ /^\Q$self->{ds}\E$/) { + next; + } elsif ($self->{filter} == 1 && $_->volume->name !~ /$self->{ds}/) { + next; + } + } + + $filter_ok = 1; $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; + push @$instances, basename($_->mountInfo->path); } } + + if ($self->{ds} ne '' and $filter_ok == 0) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status). "|Can't get a datastore with the filter '$self->{ds}'.\n"); + return ; + } # Vsphere >= 4.1 my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], - [{'label' => 'datastore.totalReadLatency.average', 'instances' => ['*']}, - {'label' => 'datastore.totalWriteLatency.average', 'instances' => ['*']}], + [{'label' => 'datastore.totalReadLatency.average', 'instances' => $instances}, + {'label' => 'datastore.totalWriteLatency.average', 'instances' => $instances}], $self->{obj_esxd}->{perfcounter_speriod}); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); @@ -107,13 +136,6 @@ sub run { my $output_critical_append = ''; my $perfdata = ''; foreach (keys %uuid_list) { - if ($self->{ds} ne '') { - if ($self->{filter} == 0 && $uuid_list{$_} !~ /^\Q$self->{ds}\E$/) { - next; - } elsif ($self->{filter} == 1 && $uuid_list{$_} !~ /$self->{ds}/) { - next; - } - } if (defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); @@ -136,17 +158,11 @@ sub run { "write on '" . $uuid_list{$_} . "' is $write_counter ms"); $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } - - $filter_ok = 1; + $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; } } - if ($self->{ds} ne '' and $filter_ok == 0) { - $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status). "|Can't get a datastore with the filter '$self->{ds}'.\n"); - return ; - } if ($output_critical ne "") { $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; $output_append = ". "; From a349a883d83e5716721fbff9e2e270aa847fce16 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 15:55:36 +0000 Subject: [PATCH 055/447] Optimize nic info from 'listnichost' command git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@76 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 8 +++++++- connectors/vmware/lib/cmdlistnichost.pm | 23 +++++++++++++++++++---- connectors/vmware/lib/cmdnethost.pm | 5 +++-- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 02278188c..7dfa91391 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -130,6 +130,7 @@ sub print_usage () { print " --nic Physical nic name to check (required)\n"; print " -w (--warning) Warning Threshold in percent (default 80)\n"; print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " --filter Use regexp for --nic option (can check multiple nics at once)\n"; print "\n"; print "'memhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -473,12 +474,17 @@ sub nethost_check_arg { if (!defined($OPTION{critical})) { $OPTION{critical} = 90; } + if (defined($OPTION{filter})) { + $OPTION{filter} = 1; + } else { + $OPTION{filter} = 0; + } return 0; } sub nethost_get_str { return join($separatorin, - ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{warning}, $OPTION{critical})); + ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical})); } sub countvmhost_check_arg { diff --git a/connectors/vmware/lib/cmdlistnichost.pm b/connectors/vmware/lib/cmdlistnichost.pm index ffc452ae9..faccda8d9 100644 --- a/connectors/vmware/lib/cmdlistnichost.pm +++ b/connectors/vmware/lib/cmdlistnichost.pm @@ -39,30 +39,45 @@ sub initArgs { sub run { my $self = shift; + my %nic_in_vswitch = (); my %filters = ('name' => $self->{lhost}); - my @properties = ('config.network.pnic'); + my @properties = ('config.network.pnic', 'config.network.vswitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } + + # Get Name from vswitch + foreach (@{$$result[0]->{'config.network.vswitch'}}) { + foreach my $keynic (@{$_->pnic}) { + $nic_in_vswitch{$keynic} = 1; + } + } my $status = 0; # OK my $output_up = 'Nic Up List: '; my $output_down = 'Nic Down List: '; + my $output_down_no_vswitch = 'Nic Down List (not in vswitch): '; my $output_up_append = ""; my $output_down_append = ""; + my $output_down_no_vswitch_append = ""; foreach (@{$$result[0]->{'config.network.pnic'}}) { if (defined($_->linkSpeed)) { $output_up .= $output_up_append . "'" . $_->device . "'"; $output_up_append = ', '; } else { - $output_down .= $output_down_append . "'" . $_->device . "'"; - $output_down_append = ', '; + if (defined($nic_in_vswitch{$_->key})) { + $output_down .= $output_down_append . "'" . $_->device . "'"; + $output_down_append = ', '; + } else { + $output_down_no_vswitch .= $output_down_no_vswitch_append . "'" . $_->device . "'"; + $output_down_no_vswitch_append = ', '; + } } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output_up. $output_down.\n"); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output_up. $output_down. $output_down_no_vswitch.\n"); } 1; diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index 7c1a80af1..619113d18 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -52,8 +52,9 @@ sub initArgs { my $self = shift; $self->{lhost} = $_[0]; $self->{pnic} = $_[1]; - $self->{warn} = (defined($_[2]) ? $_[2] : 80); - $self->{crit} = (defined($_[3]) ? $_[3] : 90); + $self->{filter} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; + $self->{warn} = (defined($_[3]) ? $_[3] : 80); + $self->{crit} = (defined($_[4]) ? $_[4] : 90); } sub run { From 0dff025c48d30be688cae950269308c06c1893f2 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 11 Sep 2013 16:08:26 +0000 Subject: [PATCH 056/447] Better error management git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@77 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/cmddatastoreusage.pm | 1 - connectors/vmware/lib/common.pm | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/lib/cmddatastoreusage.pm index a0f4062d2..5b2434ba8 100644 --- a/connectors/vmware/lib/cmddatastoreusage.pm +++ b/connectors/vmware/lib/cmddatastoreusage.pm @@ -107,7 +107,6 @@ sub run { my $capacity = $ds->summary->capacity; my $free = $ds->summary->freeSpace; - if ($self->{units} eq 'MB' && $self->{free} == 1) { $warn_threshold = $capacity - ($self->{warn} * 1024 * 1024); $crit_threshold = $capacity - ($self->{crit} * 1024 * 1024); diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index c7e01db9d..cbb047c9a 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -200,14 +200,14 @@ sub generic_performance_values_historic { #maxSample => 1); } my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => $perf_query_spec); - if (!$$perfdata[0]) { - $obj_esxd->print_response("-3|Error: Cannot get value for couters. Maybe there is time sync problem (check the esxd server and the target also).\n"); + if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { + $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe you have call a wrong instance.\n"); return undef; } foreach (@{$$perfdata[0]->value}) { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; if (!defined($_->value)) { - $obj_esxd->print_response("-3|Error: Cannot get value for couters. Maybe there is time sync problem (check the esxd server and the target also).\n"); + $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also).\n"); return undef; } } @@ -289,7 +289,7 @@ sub get_entities_host { sub performance_errors { my ($obj_esxd, $values) = @_; - # Error counter not available or orther from function + # Error counter not available or other from function return 1 if (!defined($values) || scalar(keys(%$values)) <= 0); return 0; } From 002b8c1af0a2af47eedd55c394667dd8e7236701 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 12 Sep 2013 09:49:12 +0000 Subject: [PATCH 057/447] Fix #5812 Fix #5810 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@78 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 20 +++- connectors/vmware/lib/cmddatastoreshost.pm | 1 + connectors/vmware/lib/cmddatastoreusage.pm | 19 +++- connectors/vmware/lib/cmdnethost.pm | 124 +++++++++++++++++---- connectors/vmware/lib/common.pm | 17 ++- 5 files changed, 147 insertions(+), 34 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 7dfa91391..239123bca 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -29,6 +29,7 @@ my %OPTION = ( on => undef, units => undef, free => undef, + skip_errors => undef, filter => undef, ); @@ -47,6 +48,7 @@ GetOptions( "filter" => \$OPTION{filter}, "free" => \$OPTION{free}, + "skip-errors" => \$OPTION{skip_errors}, "units=s" => \$OPTION{units}, "light-perfdata" => \$OPTION{'light-perfdata'}, "datastore=s" => \$OPTION{datastore}, @@ -106,6 +108,7 @@ sub print_usage () { print " --units Threshold units: %, MB (default is MB)\n"; print " --free Threshold is for free size\n"; print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; + print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; print "\n"; print "'datastore-io':\n"; print " --datastore Datastore name to check (required)\n"; @@ -131,6 +134,7 @@ sub print_usage () { print " -w (--warning) Warning Threshold in percent (default 80)\n"; print " -c (--critical) Critical Threshold in percent (default 90)\n"; print " --filter Use regexp for --nic option (can check multiple nics at once)\n"; + print " --skip-errors Status OK if some nic are down (when you checks multiples)\n"; print "\n"; print "'memhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -297,6 +301,11 @@ sub datastoreusage_check_arg { } else { $OPTION{free} = 0; } + if (defined($OPTION{skip_errors})) { + $OPTION{skip_errors} = 1; + } else { + $OPTION{skip_errors} = 0; + } if (!defined($OPTION{warning})) { $OPTION{warning} = ($OPTION{free} == 1) ? 20 : 80; } @@ -310,14 +319,14 @@ sub datastoreusage_check_arg { exit $ERRORS{UNKNOWN}; } } else { - $OPTION{units} = ''; + $OPTION{units} = '%'; } return 0; } sub datastoreusage_get_str { return join($separatorin, - ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units})); + ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units}, $OPTION{skip_errors})); } sub datastoreio_check_arg { @@ -479,12 +488,17 @@ sub nethost_check_arg { } else { $OPTION{filter} = 0; } + if (defined($OPTION{skip_errors})) { + $OPTION{skip_errors} = 1; + } else { + $OPTION{skip_errors} = 0; + } return 0; } sub nethost_get_str { return join($separatorin, - ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical})); + ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{skip_errors})); } sub countvmhost_check_arg { diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index 438d89819..931b90057 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -120,6 +120,7 @@ sub run { } # Vsphere >= 4.1 + # You get counters even if datastore is disconnect... my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], [{'label' => 'datastore.totalReadLatency.average', 'instances' => $instances}, diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/lib/cmddatastoreusage.pm index 5b2434ba8..b0b1c8875 100644 --- a/connectors/vmware/lib/cmddatastoreusage.pm +++ b/connectors/vmware/lib/cmddatastoreusage.pm @@ -60,6 +60,7 @@ sub initArgs { $self->{warn} = (defined($_[2]) ? $_[2] : (($self->{free} == 1) ? 20 : 80)); $self->{crit} = (defined($_[3]) ? $_[3] : (($self->{free} == 1) ? 10 : 90)); $self->{units} = (defined($_[5])) ? $_[5] : '%'; + $self->{skip_errors} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; } sub run { @@ -85,6 +86,8 @@ sub run { my $output_warning_append = ''; my $output_critical = ''; my $output_critical_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; my $output_ok_unit = ''; my $perfdata = ''; my ($warn_threshold, $crit_threshold); @@ -97,9 +100,11 @@ sub run { foreach my $ds (@$result) { if (!centreon::esxd::common::is_accessible($ds->summary->accessible)) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'" . $ds->summary->name . "' not accessible. Can be disconnected."); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + } + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $ds->summary->name . "' not accessible. Can be disconnected"); next; } @@ -150,6 +155,10 @@ sub run { } } + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - $output_unknown"; + $output_append = ". "; + } if ($output_critical ne "") { $output .= $output_append . "CRITICAL - Datastore(s): $output_critical"; $output_append = ". "; @@ -159,9 +168,9 @@ sub run { } if ($status == 0) { if ($self->{filter} == 1) { - $output = "All Datastore usages are ok"; + $output .= $output_append . "All Datastore usages are ok"; } else { - $output = $output_ok_unit; + $output .= $output_append . $output_ok_unit; } } diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index 619113d18..cb645ef73 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -23,7 +23,7 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($host, $pnic, $warn, $crit) = @_; + my ($host, $pnic, $filter, $warn, $crit) = @_; if (!defined($host) || $host eq "") { $self->{logger}->writeLogError("ARGS error: need hostname"); @@ -55,6 +55,7 @@ sub initArgs { $self->{filter} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; $self->{warn} = (defined($_[3]) ? $_[3] : 80); $self->{crit} = (defined($_[4]) ? $_[4] : 90); + $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; } sub run { @@ -67,7 +68,7 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('config.network.pnic', 'runtime.connectionState'); + my @properties = ('config.network.pnic', 'runtime.connectionState', 'config.network.vswitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; @@ -76,43 +77,124 @@ sub run { return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, $$result[0]->{'runtime.connectionState'}->val) == 0); - my %pnic_def = (); - foreach (@{$$result[0]->{'config.network.pnic'}}) { - if (defined($_->linkSpeed)) { - $pnic_def{$_->device} = $_->linkSpeed->speedMb; + my %nic_in_vswitch = (); + my %pnic_def_up = (); + my %pnic_def_down = (); + my $instances = []; + my $filter_ok = 0; + + # Get Name from vswitch + foreach (@{$$result[0]->{'config.network.vswitch'}}) { + foreach my $keynic (@{$_->pnic}) { + $nic_in_vswitch{$keynic} = 1; } } - if (!defined($pnic_def{$self->{pnic}})) { + foreach (@{$$result[0]->{'config.network.pnic'}}) { + # Not in vswitch. Skip + if (!defined($nic_in_vswitch{$_->key})) { + next; + } + + # Check filter + next if ($self->{filter} == 0 && $_->device !~ /^\Q$self->{pnic}\E$/); + next if ($self->{filter} == 1 && $_->device !~ /$self->{pnic}/); + + $filter_ok = 1; + if (defined($_->linkSpeed)) { + $pnic_def_up{$_->device} = $_->linkSpeed->speedMb; + push @$instances, $_->device; + } else { + $pnic_def_down{$_->device} = 1; + } + } + + if ($filter_ok == 0) { my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Link '" . $self->{pnic} . "' not exist or down.\n"); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't get physical nic with filter '$self->{pnic}'. (or physical nic not in a vswitch)\n"); + return ; + } + if ($#${instances} == -1) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Link(s) '" . join("','", keys %pnic_def_down) . "' is(are) down.\n"); return ; } my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], - [{'label' => 'net.received.average', 'instances' => [$self->{pnic}]}, - {'label' => 'net.transmitted.average', 'instances' => [$self->{pnic}]}], + [{'label' => 'net.received.average', 'instances' => $instances}, + {'label' => 'net.transmitted.average', 'instances' => $instances}], $self->{obj_esxd}->{perfcounter_speriod}); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{'key'} . ":" . $self->{pnic}}[0])); - my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{'key'} . ":" . $self->{pnic}}[0])); my $status = 0; # OK - my $output = ''; + my $output = ""; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; + my $output_ok_unit = ''; + my $perfdata = ''; - if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{warn} || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if (($traffic_in / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{crit} || ($traffic_out / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + my @nic_downs = keys %pnic_def_down; + if ($#nic_downs >= 0) { + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + } + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "Link(s) '" . join("','", @nic_downs) . "' is(are) down"); } - $output = "Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024 * 8) . " Mb/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024 * 8) . " Mb/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 8 * 100 / $pnic_def{$self->{pnic}}) . " %)"; - $output .= "|traffic_in=" . ($traffic_in * 1024 * 8) . "b/s traffic_out=" . (($traffic_out * 1024 * 8)) . "b/s"; + foreach (keys %pnic_def_up) { + + my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{'key'} . ":" . $_}[0])); + my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{'key'} . ":" . $_}[0])); + + $output_ok_unit = "Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 100 / $pnic_def_up{$_}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 100 / $pnic_def_up{$_}) . " %)"; + + if (($traffic_in / 1024 * 100 / $pnic_def_up{$_}) >= $self->{crit} || ($traffic_out / 1024 * 100 / $pnic_def_up{$_}) >= $self->{crit}) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ". ", + "'$_' Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 100 / $pnic_def_up{$_}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 100 / $pnic_def_up{$_}) . " %)"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (($traffic_in / 1024 * 100 / $pnic_def_up{$_}) >= $self->{warn} || ($traffic_out / 1024 * 100 / $pnic_def_up{$_}) >= $self->{warn}) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ". ", + "'$_' Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 100 / $pnic_def_up{$_}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 100 / $pnic_def_up{$_}) . " %)"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + + my $warn_perfdata = ($pnic_def_up{$_} * $self->{warn} / 100) * 1024 * 1024; + my $crit_perfdata = ($pnic_def_up{$_} * $self->{crit} / 100) * 1024 * 1024; + + if ($self->{filter} == 1) { + $perfdata .= " 'traffic_in_" . $_ . "'=" . ($traffic_in * 1024) . "B/s;$warn_perfdata;$crit_perfdata;0; 'traffic_out_" . $_ . "'=" . (($traffic_out * 1024)) . "B/s;$warn_perfdata;$crit_perfdata;0;"; + } else { + $perfdata .= " traffic_in=" . ($traffic_in * 1024) . "B/s;$warn_perfdata;$crit_perfdata;0; traffic_out=" . (($traffic_out * 1024)) . "B/s;$warn_perfdata;$crit_perfdata;0;"; + } + } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - $output_unknown"; + $output_append = ". "; + } + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - $output_warning"; + } + if ($status == 0) { + if ($self->{filter} == 1) { + $output .= $output_append . "All traffics are ok"; + } else { + $output .= $output_append . $output_ok_unit; + } + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index cbb047c9a..26c04103e 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -164,10 +164,14 @@ sub get_perf_metric_ids { } sub generic_performance_values_historic { - my ($obj_esxd, $view, $perfs, $interval) = @_; + my ($obj_esxd, $view, $perfs, $interval, $skip_undef_counter) = @_; my $counter = 0; my %results; - + + if (!defined($skip_undef_counter)) { + + } + eval { my $perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); return undef if (!defined($perf_metric_ids)); @@ -205,11 +209,14 @@ sub generic_performance_values_historic { return undef; } foreach (@{$$perfdata[0]->value}) { - $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; - if (!defined($_->value)) { + if (defined($skip_undef_counter) && $skip_undef_counter == 1 && !defined($_->value)) { + results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; + next; + } elsif (!defined($_->value)) { $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also).\n"); return undef; } + $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; } }; if ($@) { @@ -358,7 +365,7 @@ sub stats_info { $$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}; + $output = "'$num_connection' total client connections | connection=$num_connection;$$args[0];$$args[1];0; requests=" . $obj_esxd->{counter}; if ($$args[1] ne '' and $num_connection >= $$args[1]) { $status = errors_mask($status, 'CRITICAL'); } elsif ($$args[0] ne '' and $num_connection >= $$args[0]) { From 2c6bb7bdd0b93655dcf03865eb8664bde1c17abc Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 12 Sep 2013 12:06:45 +0000 Subject: [PATCH 058/447] Fix #5864 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@79 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 22 ++++++++++------ connectors/vmware/lib/cmdcpuvm.pm | 32 +++++++++++++++++++++--- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 239123bca..62ad49281 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -61,11 +61,11 @@ GetOptions( "on" => \$OPTION{on}, - "w|warning=i" => \$OPTION{warning}, - "c|critical=i" => \$OPTION{critical}, + "w|warning=f" => \$OPTION{warning}, + "c|critical=f" => \$OPTION{critical}, - "warning2=i" => \$OPTION{warning2}, - "critical2=i" => \$OPTION{critical2}, + "warning2=f" => \$OPTION{warning2}, + "critical2=f" => \$OPTION{critical2}, ); if (defined($OPTION{version})) { @@ -163,8 +163,10 @@ sub print_usage () { print "\n"; print "'cpuvm':\n"; print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " -w (--warning) Warning Threshold in percent for cpu average (default 80)\n"; + print " -c (--critical) Critical Threshold in percent for cpu average (default 90)\n"; + print " --warning2 Warning Threshold in percent for cpu ready (default 5)\n"; + print " --critical2 Critical Threshold in percent for cpu ready (default 10)\n"; print "\n"; print "'toolsvm':\n"; print " --vm VM to check (required)\n"; @@ -547,12 +549,18 @@ sub cpuvm_check_arg { if (!defined($OPTION{critical})) { $OPTION{critical} = 90; } + if (!defined($OPTION{warning2})) { + $OPTION{warning2} = 5; + } + if (!defined($OPTION{critical2})) { + $OPTION{critical2} = 10; + } return 0; } sub cpuvm_get_str { return join($separatorin, - ('cpuvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); + ('cpuvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); } sub toolsvm_check_arg { diff --git a/connectors/vmware/lib/cmdcpuvm.pm b/connectors/vmware/lib/cmdcpuvm.pm index e5ac7278c..c2bed345a 100644 --- a/connectors/vmware/lib/cmdcpuvm.pm +++ b/connectors/vmware/lib/cmdcpuvm.pm @@ -23,7 +23,7 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($vm, $warn, $crit) = @_; + my ($vm, $warn, $crit, $warn2, $crit2) = @_; if (!defined($vm) || $vm eq "") { $self->{logger}->writeLogError("ARGS error: need vm hostname"); @@ -41,6 +41,18 @@ sub checkArgs { $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); return 1; } + if (defined($warn2) && $warn2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn2 threshold must be a positive number"); + return 1; + } + if (defined($crit2) && $crit2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit2 threshold must be a positive number"); + return 1; + } + if (defined($warn2) && defined($crit2) && $warn2 > $crit2) { + $self->{logger}->writeLogError("ARGS error: warn2 threshold must be lower than crit2 threshold"); + return 1; + } return 0; } @@ -49,6 +61,8 @@ sub initArgs { $self->{lvm} = $_[0]; $self->{warn} = (defined($_[1]) ? $_[1] : 80); $self->{crit} = (defined($_[2]) ? $_[2] : 90); + $self->{warn2} = (defined($_[3]) ? $_[3] : 5); + $self->{crit2} = (defined($_[4]) ? $_[4] : 10); } sub run { @@ -76,14 +90,16 @@ sub run { my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $$result[0], [{'label' => 'cpu.usage.average', 'instances' => \@instances}, - {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], + {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, + {'label' => 'cpu.ready.summation', 'instances' => \@instances}], $self->{obj_esxd}->{perfcounter_speriod}); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - + my $status = 0; # OK my $output = ''; my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_ready = centreon::esxd::common::simplify_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{obj_esxd}->{perfcounter_speriod} * 1000) * 100); if ($total_cpu_average >= $self->{warn}) { $status = centreon::esxd::common::errors_mask($status, 'WARNING'); @@ -91,8 +107,15 @@ sub run { if ($total_cpu_average >= $self->{crit}) { $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); } + if ($total_cpu_ready >= $self->{warn2}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if ($total_cpu_ready >= $self->{crit2}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } + - $output = "Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; + $output = "CPU ready '$total_cpu_ready%', Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_ready=$total_cpu_ready%;$self->{warn2};$self->{crit2};0; cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; @@ -100,6 +123,7 @@ sub run { $cib = -1 if (!defined($cib) || $cib eq ""); $cia <=> $cib} keys %$values) { my ($counter_id, $instance) = split /:/, $id; + next if ($self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} != $counter_id); if ($instance ne "") { $output .= " cpu" . $instance . "_MHz=" . centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$id}[0])) . "MHz"; } From 8b4feb1828405e53fc3dea02b4d0a67865f8e232 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 12 Sep 2013 12:29:25 +0000 Subject: [PATCH 059/447] Fix #3864 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@80 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 36 +++++++++++++++++++++-- connectors/vmware/lib/cmdlistdatastore.pm | 16 +++++++++- connectors/vmware/lib/cmdlistnichost.pm | 17 ++++++++++- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 62ad49281..9eadbe8fa 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -31,6 +31,10 @@ my %OPTION = ( free => undef, skip_errors => undef, filter => undef, + + # For Autodisco + xml => undef, + show_attributes => undef, ); Getopt::Long::Configure('bundling'); @@ -66,6 +70,9 @@ GetOptions( "warning2=f" => \$OPTION{warning2}, "critical2=f" => \$OPTION{critical2}, + + "xml" => \$OPTION{xml}, + "show-attributes" => \$OPTION{show_attributes}, ); if (defined($OPTION{version})) { @@ -202,10 +209,13 @@ sub print_usage () { print " None\n"; print "\n"; print "'listdatastore':\n"; - print " None\n"; + print " --xml centreon-autodiscovery xml format\n"; + print " --show-attributes centreon-autodiscovery attributes xml display\n"; print "\n"; print "'listnichost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; + print " --xml centreon-autodiscovery xml format\n"; + print " --show-attributes centreon-autodiscovery attributes xml display\n"; print "\n"; print "'getmap':\n"; print " -e (--esx-host) Esx Host to check\n"; @@ -704,12 +714,22 @@ sub listhost_get_str { } sub listdatastore_check_arg { + if (!defined($OPTION{xml})) { + $OPTION{xml} = 0; + } else { + $OPTION{xml} = 1; + } + if (!defined($OPTION{show_attributes})) { + $OPTION{show_attributes} = 0; + } else { + $OPTION{show_attributes} = 1; + } return 0; } sub listdatastore_get_str { return join($separatorin, - ('listdatastore', $OPTION{vsphere})); + ('listdatastore', $OPTION{vsphere}, $OPTION{xml}, $OPTION{show_attributes})); } sub listnichost_check_arg { @@ -718,12 +738,22 @@ sub listnichost_check_arg { print_usage(); exit $ERRORS{UNKNOWN}; } + if (!defined($OPTION{xml})) { + $OPTION{xml} = 0; + } else { + $OPTION{xml} = 1; + } + if (!defined($OPTION{show_attributes})) { + $OPTION{show_attributes} = 0; + } else { + $OPTION{show_attributes} = 1; + } return 0; } sub listnichost_get_str { return join($separatorin, - ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'})); + ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{xml}, $OPTION{show_attributes})); } sub getmap_check_arg { diff --git a/connectors/vmware/lib/cmdlistdatastore.pm b/connectors/vmware/lib/cmdlistdatastore.pm index b8b0e901b..6a470d5b6 100644 --- a/connectors/vmware/lib/cmdlistdatastore.pm +++ b/connectors/vmware/lib/cmdlistdatastore.pm @@ -28,11 +28,18 @@ sub checkArgs { sub initArgs { my $self = shift; + $self->{xml} = (defined($_[0]) && $_[0] == 1) ? 1 : 0; + $self->{show_attributes} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; } sub run { my $self = shift; + if ($self->{show_attributes} == 1) { + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status(0) . "|name\n"); + return ; + } + my %filters = (); my @properties = ('summary'); @@ -44,14 +51,21 @@ sub run { my $status = 0; # OK my $output = 'Datastore List: '; my $output_append = ""; + my $xml_output = ''; foreach my $datastore (@$result) { if ($datastore->summary->accessible) { $output .= $output_append . "'" . $datastore->summary->name . "'"; $output_append = ', '; } + $xml_output .= ''; } + $xml_output .= ''; - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + if ($self->{xml} == 1) { + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$xml_output\n"); + } else { + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + } } 1; diff --git a/connectors/vmware/lib/cmdlistnichost.pm b/connectors/vmware/lib/cmdlistnichost.pm index faccda8d9..7c0e94192 100644 --- a/connectors/vmware/lib/cmdlistnichost.pm +++ b/connectors/vmware/lib/cmdlistnichost.pm @@ -35,12 +35,19 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lhost} = $_[0]; + $self->{xml} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{show_attributes} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; } sub run { my $self = shift; my %nic_in_vswitch = (); + if ($self->{show_attributes} == 1) { + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status(0) . "|name\n"); + return ; + } + my %filters = ('name' => $self->{lhost}); my @properties = ('config.network.pnic', 'config.network.vswitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); @@ -62,22 +69,30 @@ sub run { my $output_up_append = ""; my $output_down_append = ""; my $output_down_no_vswitch_append = ""; + my $xml_output = ''; foreach (@{$$result[0]->{'config.network.pnic'}}) { if (defined($_->linkSpeed)) { $output_up .= $output_up_append . "'" . $_->device . "'"; $output_up_append = ', '; + $xml_output .= ''; } else { if (defined($nic_in_vswitch{$_->key})) { $output_down .= $output_down_append . "'" . $_->device . "'"; $output_down_append = ', '; + $xml_output .= ''; } else { $output_down_no_vswitch .= $output_down_no_vswitch_append . "'" . $_->device . "'"; $output_down_no_vswitch_append = ', '; } } } + $xml_output .= ''; - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output_up. $output_down. $output_down_no_vswitch.\n"); + if ($self->{xml} == 1) { + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$xml_output\n"); + } else { + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output_up. $output_down. $output_down_no_vswitch.\n"); + } } 1; From 4286250506425f86a498a4fc8c1c95e4c731a13a Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 12 Sep 2013 13:09:18 +0000 Subject: [PATCH 060/447] Fix #5811 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@81 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 27 +++--- connectors/vmware/lib/cmdsnapshotvm.pm | 108 +++++++++++++++-------- 2 files changed, 82 insertions(+), 53 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 9eadbe8fa..b3ee75172 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -180,9 +180,9 @@ sub print_usage () { print "\n"; print "'snapshotvm':\n"; print " --vm VM to check (required)\n"; - print " --older If older than ms\n"; - print " --crit Critical if: there is a snasphot, or a snapshot is older than (--older)\n"; - print " --warn Warn if: there is a snasphot, or a snapshot is older than (--older)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --warning Warning threshold in seconds (default: 3 days)\n"; + print " --critical Critical threshold in seconds (default: 5 days)\n"; print "\n"; print "'datastoresvm':\n"; print " --vm VM to check (required)\n"; @@ -593,25 +593,23 @@ sub snapshotvm_check_arg { print_usage(); exit $ERRORS{UNKNOWN}; } - if (!defined($OPTION{older})) { - $OPTION{older} = ''; - } - if (!defined($OPTION{warn})) { - $OPTION{warn} = 0; + if (defined($OPTION{filter})) { + $OPTION{filter} = 1; } else { - $OPTION{warn} = 1; + $OPTION{filter} = 0; } - if (!defined($OPTION{crit})) { - $OPTION{crit} = 0; - } else { - $OPTION{crit} = 1; + if (!defined($OPTION{warning})) { + $OPTION{warning} = 86400 * 3; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 86400 * 5; } return 0; } sub snapshotvm_get_str { return join($separatorin, - ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{older}, $OPTION{warn}, $OPTION{crit})); + ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical})); } sub datastoresvm_check_arg { @@ -703,7 +701,6 @@ sub thinprovisioningvm_get_str { ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{on}, $OPTION{warn}, $OPTION{crit})); } - sub listhost_check_arg { return 0; } diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm index 19afe3ebb..75f3ffd04 100644 --- a/connectors/vmware/lib/cmdsnapshotvm.pm +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -23,14 +23,22 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($vm, $older) = @_; + my ($vm, $filter, $warn, $crit) = @_; if (!defined($vm) || $vm eq "") { $self->{logger}->writeLogError("ARGS error: need vm hostname"); return 1; } - if (defined($older) && $older ne '' && $older !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: older arg must be a positive number"); + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); return 1; } return 0; @@ -39,66 +47,90 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lvm} = $_[0]; - $self->{older} = ((defined($_[1]) and $_[1] ne '') ? $_[1] : -1); - $self->{warn} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); - $self->{crit} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{warning} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 86400 * 3); + $self->{critical} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 86400 * 5); } sub run { my $self = shift; - if ($self->{older} != -1 && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { + if ($self->{obj_esxd}->{module_date_parse_loaded} == 0) { my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Need to install Date::Parse CPAN Module.\n"); return ; } - my %filters = ('name' => $self->{lvm}); - my @properties = ('snapshot.rootSnapshotList'); + my %filters = (); + + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{lvm}\E$/; + } else { + $filters{name} = qr/$self->{lvm}/; + } + my @properties = ('snapshot.rootSnapshotList', 'name'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } my $status = 0; # OK - my $output = 'Snapshot(s) OK'; - - if (!defined($$result[0]->{'snapshot.rootSnapshotList'})) { - $output = 'No current snapshot.'; - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); - return ; - } + my $output = ""; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; + my $output_ok_unit = 'Snapshot(s) OK'; - foreach my $snapshot (@{$$result[0]->{'snapshot.rootSnapshotList'}}) { - if ($self->{older} != -1) { + foreach my $virtual (@$result) { + if (!defined($virtual->{'snapshot.rootSnapshotList'})) { + next; + } + + foreach my $snapshot (@{$virtual->{'snapshot.rootSnapshotList'}}) { # 2012-09-21T14:16:17.540469Z my $create_time = Date::Parse::str2time($snapshot->createTime); if (!defined($create_time)) { - $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't Parse date '" . $snapshot->createTime . "'.\n"); - return ; + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "Can't Parse date '" . $snapshot->createTime . "' for vm '" . $virtual->{'name'} . "'"); + next; } - if (time() - $create_time > $self->{older}) { - if ($self->{warn} == 1) { - $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if ($self->{crit} == 1) { - $output = 'Older snapshot problem (' . $snapshot->createTime . ').'; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } - } - } elsif ($self->{older} == -1) { - if ($self->{warn} == 1) { - $output = 'There is at least one snapshot.'; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if ($self->{crit} == 1) { - $output = 'There is at least one snapshot.'; + if (time() - $create_time >= $self->{critical}) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "[" . $virtual->{'name'}. "]"); $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + last; + } elsif (time() - $create_time >= $self->{warning}) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "[" . $virtual->{'name'}. "]"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + last; } } } + + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - $output_unknown"; + $output_append = ". "; + } + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Snapshots for VM older than " . ($self->{critical} / 86400) . " days: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "CRITICAL - Snapshots for VM older than " . ($self->{warning} / 86400) . " days: $output_warning"; + } + if ($status == 0) { + if ($self->{filter} == 1) { + $output .= $output_append . "All snapshots are ok"; + } else { + $output .= $output_append . $output_ok_unit; + } + } $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } From 840697991bd66d903b142ac7ef121c9a1268b028 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 12 Sep 2013 14:13:16 +0000 Subject: [PATCH 061/447] + Add limit command git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@82 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 37 +++++- connectors/vmware/centreonesxd.pm | 1 + connectors/vmware/lib/cmdlimitvm.pm | 136 +++++++++++++++++++++++ connectors/vmware/lib/cmdsnapshotvm.pm | 2 +- 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 connectors/vmware/lib/cmdlimitvm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index b3ee75172..03dc55951 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -184,6 +184,12 @@ sub print_usage () { print " --warning Warning threshold in seconds (default: 3 days)\n"; print " --critical Critical threshold in seconds (default: 5 days)\n"; print "\n"; + print "'limitvm':\n"; + print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --warn Warning threshold if set (default)\n"; + print " --crit Critical threshold if set\n"; + print "\n"; print "'datastoresvm':\n"; print " --vm VM to check (required)\n"; print " -w (--warning) Warning Threshold in IOPS (default none)\n"; @@ -612,6 +618,35 @@ sub snapshotvm_get_str { ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical})); } +sub limitvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (defined($OPTION{filter})) { + $OPTION{filter} = 1; + } else { + $OPTION{filter} = 0; + } + if ((!defined($OPTION{warn}) && !defined($OPTION{crit})) || defined($OPTION{warn})) { + $OPTION{warn} = 1; + } else { + $OPTION{warn} = 0; + } + if (!defined($OPTION{crit})) { + $OPTION{crit} = 0; + } else { + $OPTION{crit} = 1; + } + return 0; +} + +sub limitvm_get_str { + return join($separatorin, + ('limitvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warn}, $OPTION{crit})); +} + sub datastoresvm_check_arg { if (!defined($OPTION{vm})) { print "Option --vm is required\n"; @@ -794,7 +829,7 @@ if (!defined($OPTION{usage})) { print_usage(); exit $ERRORS{UNKNOWN}; } -if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|limitvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{UNKNOWN}; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index a87f8bca6..eb704b954 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -31,6 +31,7 @@ my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmddatastoreusage', 'centreon::esxd::cmdgetmap', 'centreon::esxd::cmdhealthhost', + 'centreon::esxd::cmdlimitvm', 'centreon::esxd::cmdlistdatastore', 'centreon::esxd::cmdlisthost', 'centreon::esxd::cmdlistnichost', diff --git a/connectors/vmware/lib/cmdlimitvm.pm b/connectors/vmware/lib/cmdlimitvm.pm new file mode 100644 index 000000000..974d7f1da --- /dev/null +++ b/connectors/vmware/lib/cmdlimitvm.pm @@ -0,0 +1,136 @@ + +package centreon::esxd::cmdlimitvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'limitvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($vm) = @_; + + if (!defined($vm) || $vm eq "") { + $self->{logger}->writeLogError("ARGS error: need vm hostname"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{lvm} = $_[0]; + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{warn} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; + $self->{crit} = (defined($_[3]) && $_[3] == 1) ? 1 : 0; + if ($self->{warn} == 0 && $self->{crit} == 0) { + $self->{warn} = 1; + } +} + +sub run { + my $self = shift; + + my %filters = (); + + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{lvm}\E$/; + } else { + $filters{name} = qr/$self->{lvm}/; + } + my @properties = ('name', 'config.hardware.device', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + my $status = 0; # OK + my $output = ""; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; + + foreach my $virtual (@$result) { + my $limit_set_warn = ''; + my $limit_set_crit = ''; + + # CPU Limit + if ($self->{crit} == 1 && defined($virtual->{'config.cpuAllocation.limit'}) && $virtual->{'config.cpuAllocation.limit'} != -1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $limit_set_crit = "/CPU" + } elsif ($self->{warn} == 1 && defined($virtual->{'config.cpuAllocation.limit'}) && $virtual->{'config.cpuAllocation.limit'} != -1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $limit_set_warn = "/CPU" + } + + # Memory Limit + if ($self->{crit} == 1 && defined($virtual->{'config.memoryAllocation.limit'}) && $virtual->{'config.memoryAllocation.limit'} != -1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $limit_set_crit .= "/MEM" + } elsif ($self->{warn} == 1 && defined($virtual->{'config.memoryAllocation.limit'}) && $virtual->{'config.memoryAllocation.limit'} != -1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $limit_set_warn .= "/MEM" + } + + # Disk + foreach my $device (@{$virtual->{'config.hardware.device'}}) { + if ($device->isa('VirtualDisk')) { + if ($self->{crit} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $limit_set_crit .= "/DISK" + } elsif ($self->{warn} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $limit_set_warn .= "/DISK" + } + } + } + + # Set + if ($limit_set_crit ne '') { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "[" . $virtual->{'name'}. "]$limit_set_crit"); + } elsif ($limit_set_warn ne '') { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "[" . $virtual->{'name'}. "]$limit_set_warn"); + } + + } + + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - $output_unknown"; + $output_append = ". "; + } + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Limits for VMs: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Limits for VMs: $output_warning"; + } + if ($status == 0) { + $output .= $output_append . "Limits are ok"; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); +} + +1; diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm index 75f3ffd04..70de92275 100644 --- a/connectors/vmware/lib/cmdsnapshotvm.pm +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -122,7 +122,7 @@ sub run { $output_append = ". "; } if ($output_warning ne "") { - $output .= $output_append . "CRITICAL - Snapshots for VM older than " . ($self->{warning} / 86400) . " days: $output_warning"; + $output .= $output_append . "WARNING - Snapshots for VM older than " . ($self->{warning} / 86400) . " days: $output_warning"; } if ($status == 0) { if ($self->{filter} == 1) { From 452e7cdbbd218f19680489a9ade3d73a850c3dab Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 4 Oct 2013 22:06:50 +0000 Subject: [PATCH 062/447] Fix errors and better management vsphere4/5 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@83 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 1681 ++++++++--------- .../vmware/lib/cmddatastoresnapshots.pm | 178 +- connectors/vmware/lib/cmddatastoreusage.pm | 7 +- connectors/vmware/lib/cmdlimitvm.pm | 28 +- connectors/vmware/lib/cmdsnapshotvm.pm | 22 +- connectors/vmware/lib/common.pm | 3 +- 6 files changed, 993 insertions(+), 926 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 03dc55951..c818ab593 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -1,866 +1,815 @@ -#!/usr/bin/perl -w - -use strict; -no strict "refs"; -use IO::Socket; -use Getopt::Long; - -my $PROGNAME = $0; -my $VERSION = "1.5.0"; -my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); -my $socket; -my $separatorin = '~'; - -sub print_help(); -sub print_usage(); -sub print_revision($$); - -my %OPTION = ( - help => undef, version => undef, - "esxd-host" => undef, "esxd-port" => 5700, - vsphere => '', - usage => undef, - "light-perfdata" => undef, - "esx-host" => undef, - datastore => undef, - nic => undef, - warning => undef, - critical => undef, - on => undef, - units => undef, - free => undef, - skip_errors => undef, - filter => undef, - - # For Autodisco - xml => undef, - show_attributes => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions( - "h|help" => \$OPTION{help}, - "V|version" => \$OPTION{version}, - "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, - "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, - - "vsphere=s" => \$OPTION{vsphere}, - - "u|usage=s" => \$OPTION{usage}, - "e|esx-host=s" => \$OPTION{'esx-host'}, - "vm=s" => \$OPTION{vm}, - - "filter" => \$OPTION{filter}, - "free" => \$OPTION{free}, - "skip-errors" => \$OPTION{skip_errors}, - "units=s" => \$OPTION{units}, - "light-perfdata" => \$OPTION{'light-perfdata'}, - "datastore=s" => \$OPTION{datastore}, - - "nic=s" => \$OPTION{nic}, - - "older=i" => \$OPTION{older}, - "warn" => \$OPTION{warn}, - "crit" => \$OPTION{crit}, - - "on" => \$OPTION{on}, - - "w|warning=f" => \$OPTION{warning}, - "c|critical=f" => \$OPTION{critical}, - - "warning2=f" => \$OPTION{warning2}, - "critical2=f" => \$OPTION{critical2}, - - "xml" => \$OPTION{xml}, - "show-attributes" => \$OPTION{show_attributes}, -); - -if (defined($OPTION{version})) { - print_revision($PROGNAME, $VERSION); - exit $ERRORS{OK}; -} - -if (defined($OPTION{help})) { - print_help(); - exit $ERRORS{OK}; -} - -############# -# Functions # -############# - -sub print_usage () { - print "Usage: "; - print $PROGNAME."\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; - print " -H centreon-esxd Host (required)\n"; - print " -P centreon-esxd Port (default 5700)\n"; - print " --vsphere vsphere name (default: none)\n"; - print " -u (--usage) What to check. The list and args (required)\n"; - print "\n"; - print "'healthhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'maintenancehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'statushost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'datastore-usage':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold (default 80)\n"; - print " -c (--critical) Critical Threshold (default 90)\n"; - print " --units Threshold units: %, MB (default is MB)\n"; - print " --free Threshold is for free size\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; - print "\n"; - print "'datastore-io':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in kBps (default none)\n"; - print " -c (--critical) Critical Threshold in kBps (default none)\n"; - print "\n"; - print "'datastore-snapshots':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; - print " -c (--critical) Critical Threshold in bytes for all snapshots (default none)\n"; - print " --warning2 Warning Threshold in bytes for one snapshot (default none)\n"; - print " --critical2 Critical Threshold in bytes for one snapshot (default none)\n"; - print "\n"; - print "'cpuhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print " --light-perfdata Display only total average cpu perfdata\n"; - print "\n"; - print "'nethost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --nic Physical nic name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print " --filter Use regexp for --nic option (can check multiple nics at once)\n"; - print " --skip-errors Status OK if some nic are down (when you checks multiples)\n"; - print "\n"; - print "'memhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'swaphost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; - print "'datastoreshost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; - print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; - print " --datastore Datastores to check (can use a regexp with --filter)\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print "\n"; - print "'countvmhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold (default none)\n"; - print " -c (--critical) Critical Threshold (default none)\n"; - print "\n"; - print "'uptimehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'cpuvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent for cpu average (default 80)\n"; - print " -c (--critical) Critical Threshold in percent for cpu average (default 90)\n"; - print " --warning2 Warning Threshold in percent for cpu ready (default 5)\n"; - print " --critical2 Critical Threshold in percent for cpu ready (default 10)\n"; - print "\n"; - print "'toolsvm':\n"; - print " --vm VM to check (required)\n"; - print "\n"; - print "'snapshotvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --warning Warning threshold in seconds (default: 3 days)\n"; - print " --critical Critical threshold in seconds (default: 5 days)\n"; - print "\n"; - print "'limitvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --warn Warning threshold if set (default)\n"; - print " --crit Critical threshold if set\n"; - print "\n"; - print "'datastoresvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in IOPS (default none)\n"; - print " -c (--critical) Critical Threshold in IOPS (default none)\n"; - print "\n"; - print "'memvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'swapvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; - print "'thinprovisioningvm':\n"; - print " --vm VM to check (required)\n"; - print " --on Warn or critical if thinprovisioning set\n"; - print " --crit Critical\n"; - print " --warn Warn\n"; - print "\n"; - print "'listhost':\n"; - print " None\n"; - print "\n"; - print "'listdatastore':\n"; - print " --xml centreon-autodiscovery xml format\n"; - print " --show-attributes centreon-autodiscovery attributes xml display\n"; - print "\n"; - print "'listnichost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --xml centreon-autodiscovery xml format\n"; - print " --show-attributes centreon-autodiscovery attributes xml display\n"; - print "\n"; - print "'getmap':\n"; - print " -e (--esx-host) Esx Host to check\n"; - print "\n"; - print "'stats':\n"; - print " -w (--warning) Warning Threshold in total client connections (default none)\n"; - print " -c (--critical) Critical Threshold in total client connections (default none)\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2005-2013 Centreon #\n"; - print "# Bugs to http://redmine.merethis.net/ #\n"; - print "##############################################\n"; - print "\n"; - print_usage(); - print "\n"; -} - -sub print_revision($$) { - my $commandName = shift; - my $pluginRevision = shift; - print "$commandName v$pluginRevision (centreon-esxd)\n"; -} - -sub myconnect { - if (!($socket = IO::Socket::INET->new( Proto => "tcp", - PeerAddr => $OPTION{'esxd-host'}, - PeerPort => $OPTION{'esxd-port'}))) { - print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; - exit $ERRORS{UNKNOWN}; - } - $socket->autoflush(1); -} - -################# -# Func Usage -################# - -sub maintenancehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub maintenancehost_get_str { - return join($separatorin, - ('maintenancehost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub statushost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub statushost_get_str { - return join($separatorin, - ('statushost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub healthhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub healthhost_get_str { - return join($separatorin, - ('healthhost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub datastoreusage_check_arg { - if (!defined($OPTION{datastore})) { - print "Option --datastore is required.\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (defined($OPTION{filter})) { - $OPTION{filter} = 1; - } else { - $OPTION{filter} = 0; - } - if (defined($OPTION{free})) { - $OPTION{free} = 1; - } else { - $OPTION{free} = 0; - } - if (defined($OPTION{skip_errors})) { - $OPTION{skip_errors} = 1; - } else { - $OPTION{skip_errors} = 0; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ($OPTION{free} == 1) ? 20 : 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ($OPTION{free} == 1) ? 10 : 90; - } - if (defined($OPTION{units})) { - if ($OPTION{units} ne '%' && $OPTION{units} ne 'MB') { - print "Option --units accept '%' or 'MB'.\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - } else { - $OPTION{units} = '%'; - } - return 0; -} - -sub datastoreusage_get_str { - return join($separatorin, - ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units}, $OPTION{skip_errors})); -} - -sub datastoreio_check_arg { - if (!defined($OPTION{'datastore'})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - return 0; -} - -sub datastoreio_get_str { - return join($separatorin, - ('datastore-io', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical})); -} - -sub datastoresnapshots_check_arg { - if (!defined($OPTION{datastore})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - if (!defined($OPTION{warning2})) { - $OPTION{warning2} = ''; - } - if (!defined($OPTION{critical2})) { - $OPTION{critical2} = ''; - } - return 0; -} - -sub datastoresnapshots_get_str { - return join($separatorin, - ('datastore-snapshots', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); -} - -sub cpuhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - if (!defined($OPTION{'light-perfdata'})) { - $OPTION{'light-perfdata'} = 0; - } - return 0; -} - -sub cpuhost_get_str { - return join($separatorin, - ('cpuhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical}, $OPTION{'light-perfdata'})); -} - -sub datastoreshost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - if (!defined($OPTION{datastore})) { - $OPTION{datastore} = ''; - } - if (defined($OPTION{filter})) { - $OPTION{filter} = 1; - } else { - $OPTION{filter} = 0; - } - return 0; -} - -sub datastoreshost_get_str { - return join($separatorin, - ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical} , $OPTION{datastore}, $OPTION{filter})); -} - -sub memhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - return 0; -} - -sub memhost_get_str { - return join($separatorin, - ('memhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); -} - -sub swaphost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 0.8; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 1; - } - return 0; -} - -sub swaphost_get_str { - return join($separatorin, - ('swaphost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); -} - -sub nethost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{nic})) { - print "Option --nic is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - if (defined($OPTION{filter})) { - $OPTION{filter} = 1; - } else { - $OPTION{filter} = 0; - } - if (defined($OPTION{skip_errors})) { - $OPTION{skip_errors} = 1; - } else { - $OPTION{skip_errors} = 0; - } - return 0; -} - -sub nethost_get_str { - return join($separatorin, - ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{skip_errors})); -} - -sub countvmhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - return 0; -} - -sub countvmhost_get_str { - return join($separatorin, - ('countvmhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); -} - -sub uptimehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub uptimehost_get_str { - return join($separatorin, - ('uptimehost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub cpuvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - if (!defined($OPTION{warning2})) { - $OPTION{warning2} = 5; - } - if (!defined($OPTION{critical2})) { - $OPTION{critical2} = 10; - } - return 0; -} - -sub cpuvm_get_str { - return join($separatorin, - ('cpuvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); -} - -sub toolsvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub toolsvm_get_str { - return join($separatorin, - ('toolsvm', $OPTION{vsphere}, $OPTION{vm})); -} - -sub snapshotvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (defined($OPTION{filter})) { - $OPTION{filter} = 1; - } else { - $OPTION{filter} = 0; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 86400 * 3; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 86400 * 5; - } - return 0; -} - -sub snapshotvm_get_str { - return join($separatorin, - ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical})); -} - -sub limitvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (defined($OPTION{filter})) { - $OPTION{filter} = 1; - } else { - $OPTION{filter} = 0; - } - if ((!defined($OPTION{warn}) && !defined($OPTION{crit})) || defined($OPTION{warn})) { - $OPTION{warn} = 1; - } else { - $OPTION{warn} = 0; - } - if (!defined($OPTION{crit})) { - $OPTION{crit} = 0; - } else { - $OPTION{crit} = 1; - } - return 0; -} - -sub limitvm_get_str { - return join($separatorin, - ('limitvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warn}, $OPTION{crit})); -} - -sub datastoresvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - return 0; -} - -sub datastoresvm_get_str { - return join($separatorin, - ('datastoresvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); -} - -sub memvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - return 0; -} - -sub memvm_get_str { - return join($separatorin, - ('memvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); -} - -sub swapvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 0.8; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 1; - } - return 0; -} - -sub swapvm_get_str { - return join($separatorin, - ('swapvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); -} - -sub thinprovisioningvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{on})) { - $OPTION{on} = 0; - } else { - $OPTION{on} = 1; - } - if (!defined($OPTION{warn})) { - $OPTION{warn} = 0; - } else { - $OPTION{warn} = 1; - } - if (!defined($OPTION{crit})) { - $OPTION{crit} = 0; - } else { - $OPTION{crit} = 1; - } - return 0; -} - -sub thinprovisioningvm_get_str { - return join($separatorin, - ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{on}, $OPTION{warn}, $OPTION{crit})); -} - -sub listhost_check_arg { - return 0; -} - -sub listhost_get_str { - return join($separatorin, - ('listhost', $OPTION{vsphere})); -} - -sub listdatastore_check_arg { - if (!defined($OPTION{xml})) { - $OPTION{xml} = 0; - } else { - $OPTION{xml} = 1; - } - if (!defined($OPTION{show_attributes})) { - $OPTION{show_attributes} = 0; - } else { - $OPTION{show_attributes} = 1; - } - return 0; -} - -sub listdatastore_get_str { - return join($separatorin, - ('listdatastore', $OPTION{vsphere}, $OPTION{xml}, $OPTION{show_attributes})); -} - -sub listnichost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{xml})) { - $OPTION{xml} = 0; - } else { - $OPTION{xml} = 1; - } - if (!defined($OPTION{show_attributes})) { - $OPTION{show_attributes} = 0; - } else { - $OPTION{show_attributes} = 1; - } - return 0; -} - -sub listnichost_get_str { - return join($separatorin, - ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{xml}, $OPTION{show_attributes})); -} - -sub getmap_check_arg { - if (!defined($OPTION{'esx-host'})) { - $OPTION{'esx-host'} = ""; - } - return 0; -} - -sub getmap_get_str { - return join($separatorin, - ('getmap', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub stats_check_arg { - if (!defined($OPTION{warning})) { - $OPTION{warning} = ""; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ""; - } - return 0; -} - -sub stats_get_str { - return join($separatorin, - ('stats', $OPTION{warning}, $OPTION{critical})); -} - -################# -################# - -if (!defined($OPTION{'esxd-host'})) { - print "Option -H (--esxd-host) is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; -} - -if (!defined($OPTION{usage})) { - print "Option -u (--usage) is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; -} -if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|limitvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { - print "Usage value is unknown\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; -} - -$OPTION{'usage'} =~ s/-//g; -my $func_check_arg = $OPTION{'usage'} . "_check_arg"; -my $func_get_str = $OPTION{'usage'} . "_get_str"; -&$func_check_arg(); -my $str_send = &$func_get_str(); -myconnect(); -print $socket "$str_send\n"; -my $return = <$socket>; -close $socket; - -chomp $return; -$return =~ /^(-?[0-9]*?)\|/; -my $status_return = $1; -$return =~ s/^(-?[0-9]*?)\|//; -print $return . "\n"; - -if ($status_return < 0) { - $status_return = 3; -} -exit $status_return; - -#print $remote "healthhost||srvi-esx-dev-1.merethis.net\n"; -#print $remote "datastores||LUN-VMFS-QGARNIER|80|90\n"; -#print $remote "maintenancehost||srvi-esx-dev-1.merethis.net\n"; -#print $remote "statushost||srvi-esx-dev-1.merethis.net\n"; -#print $remote "cpuhost||srvi-esx-dev-1.merethis.net|60\n"; -#print $remote "nethost||srvi-esx-dev-1.merethis.net|vmnic1|60\n"; -#print $remote "memhost||srvi-esx-dev-1.merethis.net|80\n"; -#print $remote "swaphost||srvi-esx-dev-1.merethis.net|80\n"; +#!/usr/bin/perl -w + +use strict; +no strict "refs"; +use IO::Socket; +use Getopt::Long; + +my $PROGNAME = $0; +my $VERSION = "1.5.0"; +my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); +my $socket; +my $separatorin = '~'; + +sub print_help(); +sub print_usage(); +sub print_revision($$); + +my %OPTION = ( + help => undef, version => undef, + "esxd-host" => undef, "esxd-port" => 5700, + vsphere => '', + usage => undef, + "light-perfdata" => undef, + "esx-host" => undef, + datastore => undef, + nic => undef, + warning => undef, + critical => undef, + on => undef, + units => undef, + free => undef, + skip_errors => undef, + filter => undef, + + consolidation => undef, + check_disk_limit => undef, + + # For Autodisco + xml => undef, + show_attributes => undef, +); + +Getopt::Long::Configure('bundling'); +GetOptions( + "h|help" => \$OPTION{help}, + "V|version" => \$OPTION{version}, + "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, + "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, + + "vsphere=s" => \$OPTION{vsphere}, + + "u|usage=s" => \$OPTION{usage}, + "e|esx-host=s" => \$OPTION{'esx-host'}, + "vm=s" => \$OPTION{vm}, + + "filter" => \$OPTION{filter}, + "free" => \$OPTION{free}, + "skip-errors" => \$OPTION{skip_errors}, + "units=s" => \$OPTION{units}, + "light-perfdata" => \$OPTION{'light-perfdata'}, + "datastore=s" => \$OPTION{datastore}, + + "nic=s" => \$OPTION{nic}, + + "older=i" => \$OPTION{older}, + "warn" => \$OPTION{warn}, + "crit" => \$OPTION{crit}, + + "on" => \$OPTION{on}, + "check-consolidation" => \$OPTION{consolidation}, + "check-disk" => \$OPTION{check_disk_limit}, + + "w|warning:f" => \$OPTION{warning}, + "c|critical:f" => \$OPTION{critical}, + + "warning2:f" => \$OPTION{warning2}, + "critical2:f" => \$OPTION{critical2}, + + "xml" => \$OPTION{xml}, + "show-attributes" => \$OPTION{show_attributes}, +); + +if (defined($OPTION{version})) { + print_revision($PROGNAME, $VERSION); + exit $ERRORS{OK}; +} + +if (defined($OPTION{help})) { + print_help(); + exit $ERRORS{OK}; +} + +############# +# Functions # +############# + +sub print_usage () { + print "Usage: "; + print $PROGNAME."\n"; + print " -V (--version) Plugin version\n"; + print " -h (--help) usage help\n"; + print " -H centreon-esxd Host (required)\n"; + print " -P centreon-esxd Port (default 5700)\n"; + print " --vsphere vsphere name (default: none)\n"; + print " -u (--usage) What to check. The list and args (required)\n"; + print "\n"; + print "'healthhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'maintenancehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'statushost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'datastore-usage':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold (default 80)\n"; + print " -c (--critical) Critical Threshold (default 90)\n"; + print " --units Threshold units: %, MB (default is MB)\n"; + print " --free Threshold is for free size\n"; + print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; + print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; + print "\n"; + print "'datastore-io':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in kBps (default none)\n"; + print " -c (--critical) Critical Threshold in kBps (default none)\n"; + print "\n"; + print "'datastore-snapshots':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; + print " -c (--critical) Critical Threshold in bytes for all snapshots (default none)\n"; + print " --warning2 Warning Threshold in bytes for one snapshot (default none)\n"; + print " --critical2 Critical Threshold in bytes for one snapshot (default none)\n"; + print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; + print " --skip-errors Status OK if not enough permissions or others errors (when you checks multiples)\n"; + print "\n"; + print "'cpuhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " --light-perfdata Display only total average cpu perfdata\n"; + print "\n"; + print "'nethost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " --nic Physical nic name to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " --filter Use regexp for --nic option (can check multiple nics at once)\n"; + print " --skip-errors Status OK if some nic are down (when you checks multiples)\n"; + print "\n"; + print "'memhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'swaphost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; + print "'datastoreshost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; + print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; + print " --datastore Datastores to check (can use a regexp with --filter)\n"; + print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; + print "\n"; + print "'countvmhost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " -w (--warning) Warning Threshold (default none)\n"; + print " -c (--critical) Critical Threshold (default none)\n"; + print "\n"; + print "'uptimehost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print "\n"; + print "'cpuvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in percent for cpu average (default 80)\n"; + print " -c (--critical) Critical Threshold in percent for cpu average (default 90)\n"; + print " --warning2 Warning Threshold in percent for cpu ready (default 5)\n"; + print " --critical2 Critical Threshold in percent for cpu ready (default 10)\n"; + print "\n"; + print "'toolsvm':\n"; + print " --vm VM to check (required)\n"; + print "\n"; + print "'snapshotvm':\n"; + print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --warning Warning threshold in seconds (default: 3 days)\n"; + print " --critical Critical threshold in seconds (default: 5 days)\n"; + print " --check-consolidation Check if VM needs consolidation (since vsphere 5.0)\n"; + print "\n"; + print "'limitvm':\n"; + print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --warn Warning threshold if set (default)\n"; + print " --crit Critical threshold if set\n"; + print " --check-disk Check Disk limits (since vsphere 5.0)\n"; + print "\n"; + print "'datastoresvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in IOPS (default none)\n"; + print " -c (--critical) Critical Threshold in IOPS (default none)\n"; + print "\n"; + print "'memvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in percent (default 80)\n"; + print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print "\n"; + print "'swapvm':\n"; + print " --vm VM to check (required)\n"; + print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; + print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; + print "\n"; + print "'thinprovisioningvm':\n"; + print " --vm VM to check (required)\n"; + print " --on Warn or critical if thinprovisioning set\n"; + print " --crit Critical\n"; + print " --warn Warn\n"; + print "\n"; + print "'listhost':\n"; + print " None\n"; + print "\n"; + print "'listdatastore':\n"; + print " --xml centreon-autodiscovery xml format\n"; + print " --show-attributes centreon-autodiscovery attributes xml display\n"; + print "\n"; + print "'listnichost':\n"; + print " -e (--esx-host) Esx Host to check (required)\n"; + print " --xml centreon-autodiscovery xml format\n"; + print " --show-attributes centreon-autodiscovery attributes xml display\n"; + print "\n"; + print "'getmap':\n"; + print " -e (--esx-host) Esx Host to check\n"; + print "\n"; + print "'stats':\n"; + print " -w (--warning) Warning Threshold in total client connections (default none)\n"; + print " -c (--critical) Critical Threshold in total client connections (default none)\n"; +} + +sub print_help () { + print "##############################################\n"; + print "# Copyright (c) 2005-2013 Centreon #\n"; + print "# Bugs to http://redmine.merethis.net/ #\n"; + print "##############################################\n"; + print "\n"; + print_usage(); + print "\n"; +} + +sub print_revision($$) { + my $commandName = shift; + my $pluginRevision = shift; + print "$commandName v$pluginRevision (centreon-esxd)\n"; +} + +sub myconnect { + if (!($socket = IO::Socket::INET->new( Proto => "tcp", + PeerAddr => $OPTION{'esxd-host'}, + PeerPort => $OPTION{'esxd-port'}))) { + print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; + exit $ERRORS{UNKNOWN}; + } + $socket->autoflush(1); +} + +################# +# Func Usage +################# + +sub maintenancehost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + return 0; +} + +sub maintenancehost_get_str { + return join($separatorin, + ('maintenancehost', $OPTION{vsphere}, $OPTION{'esx-host'})); +} + +sub statushost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + return 0; +} + +sub statushost_get_str { + return join($separatorin, + ('statushost', $OPTION{vsphere}, $OPTION{'esx-host'})); +} + +sub healthhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + return 0; +} + +sub healthhost_get_str { + return join($separatorin, + ('healthhost', $OPTION{vsphere}, $OPTION{'esx-host'})); +} + +sub datastoreusage_check_arg { + if (!defined($OPTION{datastore})) { + print "Option --datastore is required.\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{free} = (defined($OPTION{free}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); + if (!defined($OPTION{warning})) { + $OPTION{warning} = ($OPTION{free} == 1) ? 20 : 80; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ($OPTION{free} == 1) ? 10 : 90; + } + if (defined($OPTION{units})) { + if ($OPTION{units} ne '%' && $OPTION{units} ne 'MB') { + print "Option --units accept '%' or 'MB'.\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + } else { + $OPTION{units} = '%'; + } + return 0; +} + +sub datastoreusage_get_str { + return join($separatorin, + ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units}, $OPTION{skip_errors})); +} + +sub datastoreio_check_arg { + if (!defined($OPTION{'datastore'})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; + } + return 0; +} + +sub datastoreio_get_str { + return join($separatorin, + ('datastore-io', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical})); +} + +sub datastoresnapshots_check_arg { + if (!defined($OPTION{datastore})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; + } + if (!defined($OPTION{warning2})) { + $OPTION{warning2} = ''; + } + if (!defined($OPTION{critical2})) { + $OPTION{critical2} = ''; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); + return 0; +} + +sub datastoresnapshots_get_str { + return join($separatorin, + ('datastore-snapshots', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2}, $OPTION{skip_errors})); +} + +sub cpuhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; + } + if (!defined($OPTION{'light-perfdata'})) { + $OPTION{'light-perfdata'} = 0; + } + return 0; +} + +sub cpuhost_get_str { + return join($separatorin, + ('cpuhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical}, $OPTION{'light-perfdata'})); +} + +sub datastoreshost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; + } + if (!defined($OPTION{datastore})) { + $OPTION{datastore} = ''; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + return 0; +} + +sub datastoreshost_get_str { + return join($separatorin, + ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical} , $OPTION{datastore}, $OPTION{filter})); +} + +sub memhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; + } + return 0; +} + +sub memhost_get_str { + return join($separatorin, + ('memhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); +} + +sub swaphost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 0.8; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 1; + } + return 0; +} + +sub swaphost_get_str { + return join($separatorin, + ('swaphost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); +} + +sub nethost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{nic})) { + print "Option --nic is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); + return 0; +} + +sub nethost_get_str { + return join($separatorin, + ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{skip_errors})); +} + +sub countvmhost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; + } + return 0; +} + +sub countvmhost_get_str { + return join($separatorin, + ('countvmhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); +} + +sub uptimehost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + return 0; +} + +sub uptimehost_get_str { + return join($separatorin, + ('uptimehost', $OPTION{vsphere}, $OPTION{'esx-host'})); +} + +sub cpuvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; + } + if (!defined($OPTION{warning2})) { + $OPTION{warning2} = 5; + } + if (!defined($OPTION{critical2})) { + $OPTION{critical2} = 10; + } + return 0; +} + +sub cpuvm_get_str { + return join($separatorin, + ('cpuvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); +} + +sub toolsvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + return 0; +} + +sub toolsvm_get_str { + return join($separatorin, + ('toolsvm', $OPTION{vsphere}, $OPTION{vm})); +} + +sub snapshotvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{consolidation} = (defined($OPTION{consolidation}) ? 1 : 0); + if (!defined($OPTION{warning})) { + $OPTION{warning} = 86400 * 3; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 86400 * 5; + } + return 0; +} + +sub snapshotvm_get_str { + return join($separatorin, + ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{consolidation})); +} + +sub limitvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + if ((!defined($OPTION{warn}) && !defined($OPTION{crit})) || defined($OPTION{warn})) { + $OPTION{warn} = 1; + } else { + $OPTION{warn} = 0; + } + $OPTION{crit} = (defined($OPTION{crit}) ? 1 : 0); + $OPTION{check_disk_limit} = (defined($OPTION{check_disk_limit}) ? 1 : 0); + return 0; +} + +sub limitvm_get_str { + return join($separatorin, + ('limitvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warn}, $OPTION{crit}, $OPTION{check_disk_limit})); +} + +sub datastoresvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; + } + return 0; +} + +sub datastoresvm_get_str { + return join($separatorin, + ('datastoresvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); +} + +sub memvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 80; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 90; + } + return 0; +} + +sub memvm_get_str { + return join($separatorin, + ('memvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); +} + +sub swapvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = 0.8; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = 1; + } + return 0; +} + +sub swapvm_get_str { + return join($separatorin, + ('swapvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); +} + +sub thinprovisioningvm_check_arg { + if (!defined($OPTION{vm})) { + print "Option --vm is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + $OPTION{on} = (defined($OPTION{on}) ? 1 : 0); + $OPTION{warn} = (defined($OPTION{warn}) ? 1 : 0); + $OPTION{crit} = (defined($OPTION{crit}) ? 1 : 0); + return 0; +} + +sub thinprovisioningvm_get_str { + return join($separatorin, + ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{on}, $OPTION{warn}, $OPTION{crit})); +} + +sub listhost_check_arg { + return 0; +} + +sub listhost_get_str { + return join($separatorin, + ('listhost', $OPTION{vsphere})); +} + +sub listdatastore_check_arg { + $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); + $OPTION{show_attributes} = (defined($OPTION{show_attributes}) ? 1 : 0); + return 0; +} + +sub listdatastore_get_str { + return join($separatorin, + ('listdatastore', $OPTION{vsphere}, $OPTION{xml}, $OPTION{show_attributes})); +} + +sub listnichost_check_arg { + if (!defined($OPTION{'esx-host'})) { + print "Option --esx-host is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); + $OPTION{show_attributes} = (defined($OPTION{show_attributes}) ? 1 : 0); + return 0; +} + +sub listnichost_get_str { + return join($separatorin, + ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{xml}, $OPTION{show_attributes})); +} + +sub getmap_check_arg { + if (!defined($OPTION{'esx-host'})) { + $OPTION{'esx-host'} = ""; + } + return 0; +} + +sub getmap_get_str { + return join($separatorin, + ('getmap', $OPTION{vsphere}, $OPTION{'esx-host'})); +} + +sub stats_check_arg { + if (!defined($OPTION{warning})) { + $OPTION{warning} = ""; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ""; + } + return 0; +} + +sub stats_get_str { + return join($separatorin, + ('stats', $OPTION{warning}, $OPTION{critical})); +} + +################# +################# + +if (!defined($OPTION{'esxd-host'})) { + print "Option -H (--esxd-host) is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; +} + +if (!defined($OPTION{usage})) { + print "Option -u (--usage) is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; +} +if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|limitvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { + print "Usage value is unknown\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; +} + +$OPTION{'usage'} =~ s/-//g; +my $func_check_arg = $OPTION{'usage'} . "_check_arg"; +my $func_get_str = $OPTION{'usage'} . "_get_str"; +&$func_check_arg(); +my $str_send = &$func_get_str(); +myconnect(); +print $socket "$str_send\n"; +my $return = <$socket>; +close $socket; + +chomp $return; +$return =~ /^(-?[0-9]*?)\|/; +my $status_return = $1; +$return =~ s/^(-?[0-9]*?)\|//; +print $return . "\n"; + +if ($status_return < 0) { + $status_return = 3; +} +exit $status_return; + +#print $remote "healthhost||srvi-esx-dev-1.merethis.net\n"; +#print $remote "datastores||LUN-VMFS-QGARNIER|80|90\n"; +#print $remote "maintenancehost||srvi-esx-dev-1.merethis.net\n"; +#print $remote "statushost||srvi-esx-dev-1.merethis.net\n"; +#print $remote "cpuhost||srvi-esx-dev-1.merethis.net|60\n"; +#print $remote "nethost||srvi-esx-dev-1.merethis.net|vmnic1|60\n"; +#print $remote "memhost||srvi-esx-dev-1.merethis.net|80\n"; +#print $remote "swaphost||srvi-esx-dev-1.merethis.net|80\n"; diff --git a/connectors/vmware/lib/cmddatastoresnapshots.pm b/connectors/vmware/lib/cmddatastoresnapshots.pm index 3b51c3108..4f2034a6c 100644 --- a/connectors/vmware/lib/cmddatastoresnapshots.pm +++ b/connectors/vmware/lib/cmddatastoresnapshots.pm @@ -59,30 +59,45 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{ds} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : ''); - $self->{crit} = (defined($_[2]) ? $_[2] : ''); - $self->{warn2} = (defined($_[3]) ? $_[3] : ''); - $self->{crit2} = (defined($_[4]) ? $_[4] : ''); + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{warn} = (defined($_[2]) ? $_[2] : ''); + $self->{crit} = (defined($_[3]) ? $_[3] : ''); + $self->{warn2} = (defined($_[4]) ? $_[4] : ''); + $self->{crit2} = (defined($_[5]) ? $_[5] : ''); + $self->{skip_errors} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; } sub run { my $self = shift; + my %filters = (); - my %filters = ('summary.name' => $self->{ds}); - my @properties = ('summary.accessible', 'browser'); + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{ds}\E$/; + } else { + $filters{name} = qr/$self->{ds}/; + } + + my @properties = ('summary.accessible', 'summary.name', 'browser'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); if (!defined($result)) { return ; } - - return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->{'summary.accessible'}) == 0); + my @ds_array = (); + my %ds_names = (); + foreach my $entity_view (@$result) { + next if (!centreon::esxd::common::is_accessible($entity_view->{'summary.accessible'})); + if (defined($entity_view->browser)) { + push @ds_array, $entity_view->browser; + if ($self->{filter} == 1) { + $ds_names{$entity_view->{mo_ref}->{value}} = $entity_view->{'summary.name'}; + } + } + } + @properties = (); - my $browse_ds; - return if (!($browse_ds = centreon::esxd::common::get_view($self->{obj_esxd}, $$result[0]->{'browser'}, \@properties))); - - my $snapshots; - return if (!($snapshots = centreon::esxd::common::search_in_datastore($self->{obj_esxd}, $browse_ds, '[' . $self->{ds} . ']', [VmSnapshotFileQuery->new()]))); + my $result2; + return if (!($result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties))); my $status = 0; # OK my $output = ''; @@ -91,46 +106,119 @@ sub run { my $output_warning_append = ''; my $output_critical = ""; my $output_critical_append = ''; - my $total_size = 0; + my $output_warning_total = ""; + my $output_warning_total_append = ''; + my $output_critical_total = ""; + my $output_critical_total_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; + my $output_ok_unit = ''; + my $perfdata = ''; - foreach (@$snapshots) { - if (defined($_->file)) { - foreach my $x (@{$_->file}) { - if (defined($self->{crit2}) && $self->{crit2} ne '' && $x->fileSize >= $self->{crit2}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'" . $_->folderPath . ' => ' . $x->path . "'"); - } elsif (defined($self->{warn2}) && $self->{warn2} ne '' && $x->fileSize >= $self->{warn2}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'" . $_->folderPath . ' => ' . $x->path . "'"); - } - $total_size += $x->fileSize; + foreach my $browse_ds (@$result2) { + my $dsName; + if ($self->{filter} == 1) { + my $tmp_name = $browse_ds->{mo_ref}->{value}; + $tmp_name =~ s/^datastoreBrowser-//i; + $dsName = $ds_names{$tmp_name}; + } else { + $dsName = $self->{ds}; + } + + my ($snapshots, $msg) = centreon::esxd::common::search_in_datastore($self->{obj_esxd}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); + if (!defined($snapshots)) { + $msg =~ s/\n/ /g; + if ($msg =~ /NoPermissionFault/i) { + $msg = "Not enough permissions"; } + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $dsName . "' $msg"); + } + next; + } + + my $total_size = 0; + my $lwarn = ''; + my $lcrit = ''; + foreach (@$snapshots) { + if (defined($_->file)) { + foreach my $x (@{$_->file}) { + if (defined($self->{crit2}) && $self->{crit2} ne '' && $x->fileSize >= $self->{crit2}) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $lwarn .= " [" . $_->folderPath . ']=>[' . $x->path . "]"; + } elsif (defined($self->{warn2}) && $self->{warn2} ne '' && $x->fileSize >= $self->{warn2}) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $lcrit .= " [" . $_->folderPath . ']=>[' . $x->path . "]"; + } + $total_size += $x->fileSize; + } + } + } + + if ($lcrit ne '') { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "'$dsName'" . $lcrit); + } + if ($lwarn ne '') { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "'$dsName'" . $lwarn); + } + + if (defined($self->{crit}) && $self->{crit} && $total_size >= $self->{crit}) { + centreon::esxd::common::output_add(\$output_critical_total, \$output_critical_total_append, ", ", + "'$dsName' Total snapshots used " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} && $total_size >= $self->{warn}) { + centreon::esxd::common::output_add(\$output_warning_total, \$output_warning_total_append, ", ", + "'$dsName' Total snapshots used " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } else { + $output_ok_unit .= "'$dsName' Total snapshots size is ok."; + } + + if ($self->{filter} == 1) { + $perfdata .= " 'total_size_" . $dsName . "'=" . $total_size . "o;$self->{warn};$self->{crit};0;"; + } else { + $perfdata .= " 'total_size=" . $total_size . "o;$self->{warn};$self->{crit};0;"; } } - if ($output_critical ne '') { - $output .= "CRITICAL - Snapshot size exceed limit: $output_critical."; - $output_append = " "; + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - $output_unknown"; + $output_append = ". "; } - if ($output_warning ne '') { - $output .= $output_append . "WARNING - Snapshot size exceed limit: $output_warning."; - $output_append = " "; + if ($output_critical_total ne '' || $output_critical ne '') { + $output .= $output_append . "CRITICAL -"; + if ($output_critical_total ne '') { + $output .= " " . $output_critical_total; + $output_append = ' -'; + } + if ($output_critical ne '') { + $output .= $output_append . " Snapshots size exceed limit: " . $output_critical; + } + $output_append = '. '; + } + if ($output_warning_total ne '' || $output_warning ne '') { + $output .= $output_append . "WARNING -"; + if ($output_warning_total ne '') { + $output .= " " . $output_warning_total; + $output_append = ' -'; + } + if ($output_warning ne '') { + $output .= $output_append . " Snapshots size exceed limit: " . $output_warning; + } + } + if ($status == 0) { + if ($self->{filter} == 1) { + $output .= $output_append . "All Total snapshots size is ok"; + } else { + $output .= $output_append . $output_ok_unit; + } } - if (defined($self->{crit}) && $self->{crit} && $total_size >= $self->{crit}) { - $output .= $output_append . "CRITICAL - Total snapshots size exceed limit: " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB."; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} && $total_size >= $self->{warn}) { - $output .= $output_append . "WARNING - Total snapshots size exceed limit: " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB."; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } else { - $output .= $output_append . "OK - Total snapshots size is ok."; - } - $output .= "|total_size=" . $total_size . "o;$self->{warn};$self->{crit};0;"; - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/lib/cmddatastoreusage.pm index b0b1c8875..fd328f23c 100644 --- a/connectors/vmware/lib/cmddatastoreusage.pm +++ b/connectors/vmware/lib/cmddatastoreusage.pm @@ -102,11 +102,14 @@ sub run { if (!centreon::esxd::common::is_accessible($ds->summary->accessible)) { if ($self->{skip_errors} == 0 || $self->{filter} == 0) { $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $ds->summary->name . "' not accessible. Can be disconnected"); } - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $ds->summary->name . "' not accessible. Can be disconnected"); next; } + + # capacity 0... + next if ($ds->summary->capacity <= 0); my $dsName = $ds->summary->name; my $capacity = $ds->summary->capacity; diff --git a/connectors/vmware/lib/cmdlimitvm.pm b/connectors/vmware/lib/cmdlimitvm.pm index 974d7f1da..2efd2a191 100644 --- a/connectors/vmware/lib/cmdlimitvm.pm +++ b/connectors/vmware/lib/cmdlimitvm.pm @@ -38,6 +38,7 @@ sub initArgs { $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; $self->{warn} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; $self->{crit} = (defined($_[3]) && $_[3] == 1) ? 1 : 0; + $self->{disk} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; if ($self->{warn} == 0 && $self->{crit} == 0) { $self->{warn} = 1; } @@ -53,7 +54,12 @@ sub run { } else { $filters{name} = qr/$self->{lvm}/; } - my @properties = ('name', 'config.hardware.device', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); + my @properties; + push @properties, 'name', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'; + if ($self->{disk} == 1) { + push @properties, 'config.hardware.device'; + } + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; @@ -92,18 +98,20 @@ sub run { } # Disk - foreach my $device (@{$virtual->{'config.hardware.device'}}) { - if ($device->isa('VirtualDisk')) { - if ($self->{crit} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $limit_set_crit .= "/DISK" - } elsif ($self->{warn} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $limit_set_warn .= "/DISK" + if ($self->{disk} == 1) { + foreach my $device (@{$virtual->{'config.hardware.device'}}) { + if ($device->isa('VirtualDisk')) { + if ($self->{crit} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $limit_set_crit .= "/DISK" + } elsif ($self->{warn} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $limit_set_warn .= "/DISK" + } } } } - + # Set if ($limit_set_crit ne '') { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm index 70de92275..24a5712b1 100644 --- a/connectors/vmware/lib/cmdsnapshotvm.pm +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -50,6 +50,7 @@ sub initArgs { $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; $self->{warning} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 86400 * 3); $self->{critical} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 86400 * 5); + $self->{consolidate} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; } sub run { @@ -68,7 +69,12 @@ sub run { } else { $filters{name} = qr/$self->{lvm}/; } - my @properties = ('snapshot.rootSnapshotList', 'name'); + my @properties; + push @properties, 'snapshot.rootSnapshotList', 'name'; + if ($self->{consolidate} == 1) { + push @properties, 'runtime.consolidationNeeded'; + } + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; @@ -84,8 +90,16 @@ sub run { my $output_unknown = ''; my $output_unknown_append = ''; my $output_ok_unit = 'Snapshot(s) OK'; + my $consolidate_vms = ''; + my $consolidate_vms_append = ''; foreach my $virtual (@$result) { + if ($self->{consolidate} == 1 && defined($virtual->{'runtime.consolidationNeeded'}) && ($virtual->{'runtime.consolidationNeeded'} == 1 || $virtual->{'runtime.consolidationNeeded'} =~ /^true$/i)) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $consolidate_vms .= $consolidate_vms_append . '[' . $virtual->{'name'} . ']'; + $consolidate_vms_append = ', '; + } + if (!defined($virtual->{'snapshot.rootSnapshotList'})) { next; } @@ -96,7 +110,7 @@ sub run { if (!defined($create_time)) { $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "Can't Parse date '" . $snapshot->createTime . "' for vm '" . $virtual->{'name'} . "'"); + "Can't Parse date '" . $snapshot->createTime . "' for vm [" . $virtual->{'name'} . "]"); next; } if (time() - $create_time >= $self->{critical}) { @@ -117,6 +131,10 @@ sub run { $output .= $output_append . "UNKNOWN - $output_unknown"; $output_append = ". "; } + if ($consolidate_vms ne "") { + $output .= $output_append . "CRITICAL - VMs need consolidation : " . $consolidate_vms; + $output_append = ". "; + } if ($output_critical ne "") { $output .= $output_append . "CRITICAL - Snapshots for VM older than " . ($self->{critical} / 86400) . " days: $output_critical"; $output_append = ". "; diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 26c04103e..74a7cf722 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -121,7 +121,7 @@ sub get_view { sub search_in_datastore { my $obj_esxd = shift; - my ($ds_browse, $ds_name, $query) = @_; + my ($ds_browse, $ds_name, $query, $return) = @_; my $result; my $files = FileQueryFlags->new(fileSize => 1, @@ -136,6 +136,7 @@ sub search_in_datastore { searchSpec=>$hostdb_search_spec); }; if ($@) { + return (undef, $@) if (defined($return) && $return == 1); vmware_error($obj_esxd, $@); return undef; } From f75bf944ef6b0496b8e721f7009b2fe9322cc7a9 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Sun, 6 Oct 2013 12:42:45 +0000 Subject: [PATCH 063/447] Permits globals checks on somme commands git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@84 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 45 ++++++--- connectors/vmware/lib/cmdlimitvm.pm | 16 +++- connectors/vmware/lib/cmdsnapshotvm.pm | 18 +++- .../vmware/lib/cmdthinprovisioningvm.pm | 92 +++++++++++-------- connectors/vmware/lib/cmdtoolsvm.pm | 88 ++++++++++++++---- connectors/vmware/lib/common.pm | 22 ++++- 6 files changed, 206 insertions(+), 75 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index c818ab593..100557fdc 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -30,6 +30,7 @@ my %OPTION = ( units => undef, free => undef, skip_errors => undef, + skip_not_running => undef, filter => undef, consolidation => undef, @@ -53,9 +54,11 @@ GetOptions( "e|esx-host=s" => \$OPTION{'esx-host'}, "vm=s" => \$OPTION{vm}, + "skip-errors" => \$OPTION{skip_errors}, + "skip-not-running" => \$OPTION{skip_not_running}, + "filter" => \$OPTION{filter}, "free" => \$OPTION{free}, - "skip-errors" => \$OPTION{skip_errors}, "units=s" => \$OPTION{units}, "light-perfdata" => \$OPTION{'light-perfdata'}, "datastore=s" => \$OPTION{datastore}, @@ -99,10 +102,10 @@ sub print_usage () { print $PROGNAME."\n"; print " -V (--version) Plugin version\n"; print " -h (--help) usage help\n"; - print " -H centreon-esxd Host (required)\n"; - print " -P centreon-esxd Port (default 5700)\n"; - print " --vsphere vsphere name (default: none)\n"; - print " -u (--usage) What to check. The list and args (required)\n"; + print " -H centreon-esxd Host (required)\n"; + print " -P centreon-esxd Port (default 5700)\n"; + print " --vsphere vsphere name (default: none)\n"; + print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; print "'healthhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -184,6 +187,8 @@ sub print_usage () { print "\n"; print "'toolsvm':\n"; print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; print "\n"; print "'snapshotvm':\n"; print " --vm VM to check (required)\n"; @@ -191,13 +196,16 @@ sub print_usage () { print " --warning Warning threshold in seconds (default: 3 days)\n"; print " --critical Critical threshold in seconds (default: 5 days)\n"; print " --check-consolidation Check if VM needs consolidation (since vsphere 5.0)\n"; + print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; + print " --skip-not-running Skip snapshots from vms not running\n"; print "\n"; print "'limitvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --warn Warning threshold if set (default)\n"; - print " --crit Critical threshold if set\n"; - print " --check-disk Check Disk limits (since vsphere 5.0)\n"; + print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --warn Warning threshold if set (default)\n"; + print " --crit Critical threshold if set\n"; + print " --check-disk Check Disk limits (since vsphere 5.0)\n"; + print " --skip-errors Status OK if vms are disconencted (when you checks multiples)\n"; print "\n"; print "'datastoresvm':\n"; print " --vm VM to check (required)\n"; @@ -216,9 +224,11 @@ sub print_usage () { print "\n"; print "'thinprovisioningvm':\n"; print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; print " --on Warn or critical if thinprovisioning set\n"; print " --crit Critical\n"; print " --warn Warn\n"; + print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; print "\n"; print "'listhost':\n"; print " None\n"; @@ -572,12 +582,14 @@ sub toolsvm_check_arg { print_usage(); exit $ERRORS{UNKNOWN}; } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); return 0; } sub toolsvm_get_str { return join($separatorin, - ('toolsvm', $OPTION{vsphere}, $OPTION{vm})); + ('toolsvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{skip_errors})); } sub snapshotvm_check_arg { @@ -588,6 +600,8 @@ sub snapshotvm_check_arg { } $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); $OPTION{consolidation} = (defined($OPTION{consolidation}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); + $OPTION{skip_not_running} = (defined($OPTION{skip_not_running}) ? 1 : 0); if (!defined($OPTION{warning})) { $OPTION{warning} = 86400 * 3; } @@ -599,7 +613,7 @@ sub snapshotvm_check_arg { sub snapshotvm_get_str { return join($separatorin, - ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{consolidation})); + ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{consolidation}, $OPTION{skip_errors}, $OPTION{skip_not_running})); } sub limitvm_check_arg { @@ -609,6 +623,7 @@ sub limitvm_check_arg { exit $ERRORS{UNKNOWN}; } $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); if ((!defined($OPTION{warn}) && !defined($OPTION{crit})) || defined($OPTION{warn})) { $OPTION{warn} = 1; } else { @@ -621,7 +636,7 @@ sub limitvm_check_arg { sub limitvm_get_str { return join($separatorin, - ('limitvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warn}, $OPTION{crit}, $OPTION{check_disk_limit})); + ('limitvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warn}, $OPTION{crit}, $OPTION{check_disk_limit}, $OPTION{skip_errors})); } sub datastoresvm_check_arg { @@ -693,12 +708,14 @@ sub thinprovisioningvm_check_arg { $OPTION{on} = (defined($OPTION{on}) ? 1 : 0); $OPTION{warn} = (defined($OPTION{warn}) ? 1 : 0); $OPTION{crit} = (defined($OPTION{crit}) ? 1 : 0); + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); return 0; } sub thinprovisioningvm_get_str { return join($separatorin, - ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{on}, $OPTION{warn}, $OPTION{crit})); + ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{on}, $OPTION{warn}, $OPTION{crit}, $OPTION{skip_errors})); } sub listhost_check_arg { diff --git a/connectors/vmware/lib/cmdlimitvm.pm b/connectors/vmware/lib/cmdlimitvm.pm index 2efd2a191..16d5c19ff 100644 --- a/connectors/vmware/lib/cmdlimitvm.pm +++ b/connectors/vmware/lib/cmdlimitvm.pm @@ -39,6 +39,7 @@ sub initArgs { $self->{warn} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; $self->{crit} = (defined($_[3]) && $_[3] == 1) ? 1 : 0; $self->{disk} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; + $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; if ($self->{warn} == 0 && $self->{crit} == 0) { $self->{warn} = 1; } @@ -55,7 +56,7 @@ sub run { $filters{name} = qr/$self->{lvm}/; } my @properties; - push @properties, 'name', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'; + push @properties, 'name', 'runtime.connectionState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'; if ($self->{disk} == 1) { push @properties, 'config.hardware.device'; } @@ -76,6 +77,15 @@ sub run { my $output_unknown_append = ''; foreach my $virtual (@$result) { + if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $virtual->{name} . "' not connected"); + } + next; + } + my $limit_set_warn = ''; my $limit_set_crit = ''; @@ -115,10 +125,10 @@ sub run { # Set if ($limit_set_crit ne '') { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "[" . $virtual->{'name'}. "]$limit_set_crit"); + "[" . $virtual->{name}. "]$limit_set_crit"); } elsif ($limit_set_warn ne '') { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "[" . $virtual->{'name'}. "]$limit_set_warn"); + "[" . $virtual->{name}. "]$limit_set_warn"); } } diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm index 24a5712b1..45e99f4fb 100644 --- a/connectors/vmware/lib/cmdsnapshotvm.pm +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -51,6 +51,8 @@ sub initArgs { $self->{warning} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 86400 * 3); $self->{critical} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 86400 * 5); $self->{consolidate} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; + $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; + $self->{skip_not_running} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; } sub run { @@ -70,7 +72,7 @@ sub run { $filters{name} = qr/$self->{lvm}/; } my @properties; - push @properties, 'snapshot.rootSnapshotList', 'name'; + push @properties, 'snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'; if ($self->{consolidate} == 1) { push @properties, 'runtime.consolidationNeeded'; } @@ -94,6 +96,20 @@ sub run { my $consolidate_vms_append = ''; foreach my $virtual (@$result) { + if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $virtual->{name} . "' not connected"); + } + next; + } + + if ($self->{skip_not_running} == 1 && + !centreon::esxd::common::is_running($virtual->{'runtime.powerState'}->val)) { + next; + } + if ($self->{consolidate} == 1 && defined($virtual->{'runtime.consolidationNeeded'}) && ($virtual->{'runtime.consolidationNeeded'} == 1 || $virtual->{'runtime.consolidationNeeded'} =~ /^true$/i)) { $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); $consolidate_vms .= $consolidate_vms_append . '[' . $virtual->{'name'} . ']'; diff --git a/connectors/vmware/lib/cmdthinprovisioningvm.pm b/connectors/vmware/lib/cmdthinprovisioningvm.pm index 9cca1e71b..ac61547e1 100644 --- a/connectors/vmware/lib/cmdthinprovisioningvm.pm +++ b/connectors/vmware/lib/cmdthinprovisioningvm.pm @@ -35,59 +35,79 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lvm} = $_[0]; - $self->{on} = ((defined($_[1]) and $_[1] ne '') ? $_[1] : 0); - $self->{warn} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); - $self->{crit} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{on} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); + $self->{warn} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); + $self->{crit} = ((defined($_[4]) and $_[4] ne '') ? $_[4] : 0); + $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; } sub run { my $self = shift; + my %filters = (); - my %filters = ('name' => $self->{lvm}); - my @properties = ('config.hardware.device', 'runtime.connectionState'); + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{lvm}\E$/; + } else { + $filters{name} = qr/$self->{lvm}/; + } + my @properties = ('name', 'config.hardware.device', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } - return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, - $$result[0]->{'runtime.connectionState'}->val, - undef, 1) == 0); - - my $status = 0; - my $output = ""; + my $status = 0; # OK + my $output = ''; my $output_append = ''; - foreach (@{$$result[0]->{'config.hardware.device'}}) { - if ($_->isa('VirtualDisk')) { - if ($self->{on} == 1 && $self->{warn} == 1 && $_->backing->thinProvisioned == 1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - centreon::esxd::common::output_add(\$output, \$output_append, ", ", - "'" . $_->backing->fileName . "'"); + my $output_unknown = ''; + my $output_unknown_append = ''; + + foreach my $virtual (@$result) { + if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $virtual->{name} . "' not connected"); } - if ($self->{on} == 1 && $self->{crit} == 1 && $_->backing->thinProvisioned == 1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - centreon::esxd::common::output_add(\$output, \$output_append, ", ", - "'" . $_->backing->fileName . "'"); - } - if ($self->{on} == 0 && $self->{warn} == 1 && $_->backing->thinProvisioned != 1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - centreon::esxd::common::output_add(\$output, \$output_append, ", ", - "'" . $_->backing->fileName . "'"); - } - if ($self->{on} == 0 && $self->{crit} == 1 && $_->backing->thinProvisioned != 1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - centreon::esxd::common::output_add(\$output, \$output_append, ", ", - "'" . $_->backing->fileName . "'"); + next; + } + + my $output_disk = ''; + foreach (@{$virtual->{'config.hardware.device'}}) { + if ($_->isa('VirtualDisk')) { + if ($self->{on} == 1 && $self->{warn} == 1 && $_->backing->thinProvisioned == 1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $output_disk .= ' [' . $_->backing->fileName . ']'; + } + if ($self->{on} == 1 && $self->{crit} == 1 && $_->backing->thinProvisioned == 1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $output_disk .= ' [' . $_->backing->fileName . ']'; + } + if ($self->{on} == 0 && $self->{warn} == 1 && $_->backing->thinProvisioned != 1) { + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $output_disk .= ' [' . $_->backing->fileName . ']'; + } + if ($self->{on} == 0 && $self->{crit} == 1 && $_->backing->thinProvisioned != 1) { + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $output_disk .= ' [' . $_->backing->fileName . ']'; + } } } + + if ($output_disk ne '') { + centreon::esxd::common::output_add(\$output, \$output_append, ", ", + 'VM ' . $virtual->{name} . ':' . $output_disk); + } } - + if ($output ne "" && $self->{on} == 1) { - $output = "VirtualDisks $output: thinprovisioning actived."; + $output = "VirtualDisks thinprovisioning actived - $output."; } elsif ($output ne "" && $self->{on} == 0) { - $output = "VirtualDisks $output: thinprovisioning not actived."; - } else { - $output = "Thinprovisoning virtualdisks are ok."; + $output = "VirtualDisks thinprovisioning not actived - $output."; + } + if ($status == 0) { + $output .= $output_append . "Thinprovisoning virtualdisks are ok."; } $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); diff --git a/connectors/vmware/lib/cmdtoolsvm.pm b/connectors/vmware/lib/cmdtoolsvm.pm index 442778631..12f6c51a5 100644 --- a/connectors/vmware/lib/cmdtoolsvm.pm +++ b/connectors/vmware/lib/cmdtoolsvm.pm @@ -35,38 +35,88 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lvm} = $_[0]; + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{skip_errors} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; } sub run { my $self = shift; + my %filters = (); - my %filters = ('name' => $self->{lvm}); - my @properties = ('summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{lvm}\E$/; + } else { + $filters{name} = qr/$self->{lvm}/; + } + + my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); if (!defined($result)) { return ; } - return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, - $$result[0]->{'runtime.connectionState'}->val, - $$result[0]->{'runtime.powerState'}->val) == 0); - - my $status = 0; # OK my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; + my $not_installed = ''; + my $not_running = ''; + my $not_up2date = ''; - my $tools_status = lc($$result[0]->{'summary.guest.toolsStatus'}->val); - if ($tools_status eq 'toolsnotinstalled') { - $output = "VMTools not installed on VM '" . $self->{lvm} . "'."; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif ($tools_status eq 'toolsnotrunning') { - $output = "VMTools not running on VM '" . $self->{lvm} . "'."; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif ($tools_status eq 'toolsold') { - $output = "VMTools not up-to-date on VM '" . $self->{lvm} . "'."; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } else { - $output = "VMTools are OK on VM '" . $self->{lvm} . "'."; + foreach my $virtual (@$result) { + if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $virtual->{name} . "' not connected"); + } + next; + } + + my $tools_status = lc($virtual->{'summary.guest.toolsStatus'}->val); + if ($tools_status eq 'toolsnotinstalled') { + $not_installed .= ' [' . $virtual->{name} . ']'; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif ($tools_status eq 'toolsnotrunning') { + $not_running .= ' [' . $virtual->{name} . ']'; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif ($tools_status eq 'toolsold') { + $not_up2date .= ' [' . $virtual->{name} . ']'; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + } + + if ($not_installed ne '') { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "VMTools not installed on VM:" . $not_installed); + } + if ($not_running ne '') { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "VMTools not running on VM:" . $not_running); + } + if ($not_running ne '') { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "VMTools not up-to-date on VM:" . $not_running); + } + + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - " . $output_unknown; + $output_append = ". "; + } + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - " . $output_critical; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - " . $output_warning; + } + if ($status == 0) { + $output .= $output_append . "VMTools are OK."; } $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 74a7cf722..6a22442f6 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -58,9 +58,9 @@ sub connect_vsphere { alarm(0); }; if($@) { - $logger->writeLogError("'$whoaim' No response from VirtualCentre server") if($@ =~ /TIMEOUT/); + $logger->writeLogError("'$whoaim' No response from VirtualCenter server") if($@ =~ /TIMEOUT/); $logger->writeLogError("'$whoaim' You need to upgrade HTTP::Message!") if($@ =~ /HTTP::Message/); - $logger->writeLogError("'$whoaim' Login to VirtualCentre server failed: $@"); + $logger->writeLogError("'$whoaim' Login to VirtualCenter server failed: $@"); return 1; } # eval { @@ -311,6 +311,24 @@ sub is_accessible { return 1; } +sub is_connected { + my ($connection_state) = @_; + + if ($connection_state !~ /^connected$/i) { + return 0; + } + return 1; +} + +sub is_running { + my ($power_state) = @_; + + if ($power_state !~ /^poweredOn$/i) { + return 0; + } + return 1; +} + sub datastore_state { my ($obj_esxd, $ds, $accessible) = @_; From 0a3e6f1876d4d2c8b5c7791d627ca47519835e1e Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Sun, 6 Oct 2013 22:22:29 +0000 Subject: [PATCH 064/447] Working on new command 'datastore-iops' - in progress git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@85 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 33 +++- connectors/vmware/centreonesxd.pm | 1 + connectors/vmware/lib/cmdcpuhost.pm | 2 +- connectors/vmware/lib/cmdcpuvm.pm | 2 +- connectors/vmware/lib/cmddatastoreio.pm | 2 +- connectors/vmware/lib/cmddatastoreiops.pm | 189 +++++++++++++++++++++ connectors/vmware/lib/cmddatastoreshost.pm | 2 +- connectors/vmware/lib/cmddatastoresvm.pm | 2 +- connectors/vmware/lib/cmdmemhost.pm | 2 +- connectors/vmware/lib/cmdmemvm.pm | 2 +- connectors/vmware/lib/cmdnethost.pm | 2 +- connectors/vmware/lib/cmdswaphost.pm | 2 +- connectors/vmware/lib/cmdswapvm.pm | 2 +- connectors/vmware/lib/common.pm | 70 ++++---- 14 files changed, 269 insertions(+), 44 deletions(-) create mode 100644 connectors/vmware/lib/cmddatastoreiops.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 100557fdc..1a8464158 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -125,6 +125,13 @@ sub print_usage () { print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; print "\n"; + print "'datastore-iops':\n"; + print " --datastore Datastore name to check (required)\n"; + print " -w (--warning) Warning Threshold (default none)\n"; + print " -c (--critical) Critical Threshold (default none)\n"; + print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; + print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; + print "\n"; print "'datastore-io':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold in kBps (default none)\n"; @@ -354,8 +361,30 @@ sub datastoreusage_get_str { ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units}, $OPTION{skip_errors})); } +sub datastoreiops_check_arg { + if (!defined($OPTION{datastore})) { + print "Option --datastore is required\n"; + print_usage(); + exit $ERRORS{UNKNOWN}; + } + if (!defined($OPTION{warning})) { + $OPTION{warning} = ''; + } + if (!defined($OPTION{critical})) { + $OPTION{critical} = ''; + } + $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); + $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); + return 0; +} + +sub datastoreiops_get_str { + return join($separatorin, + ('datastore-iops', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{skip_errors})); +} + sub datastoreio_check_arg { - if (!defined($OPTION{'datastore'})) { + if (!defined($OPTION{datastore})) { print "Option --datastore is required\n"; print_usage(); exit $ERRORS{UNKNOWN}; @@ -795,7 +824,7 @@ if (!defined($OPTION{usage})) { print_usage(); exit $ERRORS{UNKNOWN}; } -if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|limitvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { +if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-iops|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|limitvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { print "Usage value is unknown\n"; print_usage(); exit $ERRORS{UNKNOWN}; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index eb704b954..733e943c5 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -25,6 +25,7 @@ my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', 'centreon::esxd::cmdcpuvm', 'centreon::esxd::cmddatastoreio', + 'centreon::esxd::cmddatastoreiops', 'centreon::esxd::cmddatastoreshost', 'centreon::esxd::cmddatastoresnapshots', 'centreon::esxd::cmddatastoresvm', diff --git a/connectors/vmware/lib/cmdcpuhost.pm b/connectors/vmware/lib/cmdcpuhost.pm index 58ad1e215..dca0a7241 100644 --- a/connectors/vmware/lib/cmdcpuhost.pm +++ b/connectors/vmware/lib/cmdcpuhost.pm @@ -72,7 +72,7 @@ sub run { my @instances = ('*'); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}], $self->{obj_esxd}->{perfcounter_speriod}); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); diff --git a/connectors/vmware/lib/cmdcpuvm.pm b/connectors/vmware/lib/cmdcpuvm.pm index c2bed345a..b65d83f48 100644 --- a/connectors/vmware/lib/cmdcpuvm.pm +++ b/connectors/vmware/lib/cmdcpuvm.pm @@ -88,7 +88,7 @@ sub run { my @instances = ('*'); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, {'label' => 'cpu.ready.summation', 'instances' => \@instances}], diff --git a/connectors/vmware/lib/cmddatastoreio.pm b/connectors/vmware/lib/cmddatastoreio.pm index e610d50a0..5b7e3e73e 100644 --- a/connectors/vmware/lib/cmddatastoreio.pm +++ b/connectors/vmware/lib/cmddatastoreio.pm @@ -70,7 +70,7 @@ sub run { return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->{'summary.accessible'}) == 0); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/cmddatastoreiops.pm b/connectors/vmware/lib/cmddatastoreiops.pm new file mode 100644 index 000000000..ab8a9df78 --- /dev/null +++ b/connectors/vmware/lib/cmddatastoreiops.pm @@ -0,0 +1,189 @@ + +package centreon::esxd::cmddatastoreiops; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{obj_esxd} = shift; + $self->{commandName} = 'datastore-iops'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my $self = shift; + my ($ds, $warn, $crit) = @_; + + if (!defined($ds) || $ds eq "") { + $self->{logger}->writeLogError("ARGS error: need datastore name"); + return 1; + } + if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + return 1; + } + if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + return 1; + } + if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { + $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + return 1; + } + return 0; +} + +sub initArgs { + my $self = shift; + $self->{ds} = $_[0]; + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{warn} = (defined($_[2]) ? $_[2] : ''); + $self->{crit} = (defined($_[3]) ? $_[3] : ''); + $self->{skip_errors} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + return ; + } + + my %filters = (); + if ($self->{filter} == 0) { + $filters{name} = qr/^\Q$self->{ds}\E$/; + } else { + $filters{name} = qr/$self->{ds}/; + } + + my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + if (!defined($result)) { + return ; + } + + #my %uuid_list = (); + my %disk_name = (); + my %datastore_lun = (); + foreach (@$result) { + if ($_->info->isa('VmfsDatastoreInfo')) { + #$uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + foreach my $extent (@{$_->info->vmfs->extent}) { + $disk_name{$extent->diskName} = $_->info->vmfs->name; + if (!defined($datastore_lun{$_->info->vmfs->name})) { + %{$datastore_lun{$_->info->vmfs->name}} = ('disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0); + } + } + } + #if ($_->info->isa('NasDatastoreInfo')) { + # Zero disk Info + #} + } + + use Data::Dumper; + + my @vm_array = (); + my %added_vm = (); + foreach my $entity_view (@$result) { + if (defined($entity_view->vm)) { + foreach (@{$entity_view->vm}) { + next if (defined($added_vm{$_->{value}})); + push @vm_array, $_; + $added_vm{$_->{value}} = 1; + } + } + } + + @properties = ('name', 'runtime.connectionState'); + my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + if (!defined($result2)) { + return ; + } + + my %ref_ids_vm = (); + foreach (@$result2) { + $ref_ids_vm{$_->{mo_ref}->{value}} = $_->{name}; + } + + print STDERR Data::Dumper::Dumper(%ref_ids_vm); + + # Vsphere >= 4.1 + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $result2, + [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, + {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + $self->{obj_esxd}->{perfcounter_speriod}, 1, 1); + print STDERR Data::Dumper::Dumper($values); + return ; + + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + + + + foreach (keys %$values) { + my ($id, $disk_name) = split(/:/); + $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$_}[0]; + } + + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $perfdata = ''; + foreach (keys %datastore_lun) { + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + + if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "read on '" . $_ . "' is $read_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "read on '" . $_ . "' is $read_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + "write on '" . $_ . "' is $write_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + "write on '" . $_ . "' is $write_counter ms"); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } + + $perfdata .= " 'riops_" . $_ . "'=" . $read_counter . "iops 'wiops_" . $_ . "'=" . $write_counter . 'iops'; + } + + if ($output_critical ne "") { + $output .= $output_append . "CRITICAL - Datastore IOPS counter: $output_critical"; + $output_append = ". "; + } + if ($output_warning ne "") { + $output .= $output_append . "WARNING - Datastore IOPS counter: $output_warning"; + } + if ($status == 0) { + $output = "All Datastore IOPS counters are ok"; + } + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); +} + +1; diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index 931b90057..26e063d62 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -122,7 +122,7 @@ sub run { # Vsphere >= 4.1 # You get counters even if datastore is disconnect... my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'datastore.totalReadLatency.average', 'instances' => $instances}, {'label' => 'datastore.totalWriteLatency.average', 'instances' => $instances}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/lib/cmddatastoresvm.pm index c499cee3e..13351865a 100644 --- a/connectors/vmware/lib/cmddatastoresvm.pm +++ b/connectors/vmware/lib/cmddatastoresvm.pm @@ -104,7 +104,7 @@ sub run { # Vsphere >= 4.1 my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/cmdmemhost.pm b/connectors/vmware/lib/cmdmemhost.pm index b7d90e824..88f88fadd 100644 --- a/connectors/vmware/lib/cmdmemhost.pm +++ b/connectors/vmware/lib/cmdmemhost.pm @@ -73,7 +73,7 @@ sub run { my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/cmdmemvm.pm b/connectors/vmware/lib/cmdmemvm.pm index 25d32c288..3740cad31 100644 --- a/connectors/vmware/lib/cmdmemvm.pm +++ b/connectors/vmware/lib/cmdmemvm.pm @@ -74,7 +74,7 @@ sub run { my $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'mem.active.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}, {'label' => 'mem.vmmemctl.average', 'instances' => ['']}, diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index cb645ef73..6e28604e6 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -122,7 +122,7 @@ sub run { my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'net.received.average', 'instances' => $instances}, {'label' => 'net.transmitted.average', 'instances' => $instances}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/cmdswaphost.pm b/connectors/vmware/lib/cmdswaphost.pm index 8384896e8..fbd52611f 100644 --- a/connectors/vmware/lib/cmdswaphost.pm +++ b/connectors/vmware/lib/cmdswaphost.pm @@ -71,7 +71,7 @@ sub run { $$result[0]->{'runtime.connectionState'}->val) == 0); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/cmdswapvm.pm b/connectors/vmware/lib/cmdswapvm.pm index 7c52a1e84..03a8df3f1 100644 --- a/connectors/vmware/lib/cmdswapvm.pm +++ b/connectors/vmware/lib/cmdswapvm.pm @@ -72,7 +72,7 @@ sub run { $$result[0]->{'runtime.powerState'}->val) == 0); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $$result[0], + $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 6a22442f6..6a82abd59 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -165,19 +165,15 @@ sub get_perf_metric_ids { } sub generic_performance_values_historic { - my ($obj_esxd, $view, $perfs, $interval, $skip_undef_counter) = @_; + my ($obj_esxd, $views, $perfs, $interval, $skip_undef_counter, $multiples) = @_; my $counter = 0; my %results; - if (!defined($skip_undef_counter)) { - - } - eval { my $perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); return undef if (!defined($perf_metric_ids)); - my $perf_query_spec; + my @perf_query_spec; my $tstamp = time(); my (@t) = gmtime($tstamp - $interval); my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", @@ -186,38 +182,48 @@ sub generic_performance_values_historic { 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); + foreach (@$views) { + if ($interval == 20) { + push @perf_query_spec, PerfQuerySpec->new(entity => $_, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => 20, + startTime => $startTime, + endTime => $endTime, + maxSample => 1); + } else { + push @perf_query_spec, PerfQuerySpec->new(entity => $_, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => $interval, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); + } } - my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => $perf_query_spec); + my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); + if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe you have call a wrong instance.\n"); return undef; } - foreach (@{$$perfdata[0]->value}) { - if (defined($skip_undef_counter) && $skip_undef_counter == 1 && !defined($_->value)) { - results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; - next; - } elsif (!defined($_->value)) { - $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also).\n"); - return undef; + foreach my $val (@$perfdata) { + foreach (@{$val->{value}}) { + if (defined($skip_undef_counter) && $skip_undef_counter == 1 && !defined($_->value)) { + $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; + next; + } elsif (!defined($_->value)) { + $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also).\n"); + return undef; + } + + if (defined($multiples) && $multiples == 1) { + $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + } else { + $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + } } - $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; } }; if ($@) { From bf74e6a0f0dfd1ea50b1ad905e3cbc549a7a53db Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 7 Oct 2013 18:07:33 +0000 Subject: [PATCH 065/447] Fix #5497 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@86 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 19 +++- connectors/vmware/lib/cmddatastoreiops.pm | 126 ++++++++++++++------- connectors/vmware/lib/cmddatastoreshost.pm | 10 +- connectors/vmware/lib/cmddatastoresvm.pm | 12 +- 4 files changed, 109 insertions(+), 58 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 1a8464158..ef2eacfbf 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -35,6 +35,7 @@ my %OPTION = ( consolidation => undef, check_disk_limit => undef, + details_value => undef, # For Autodisco xml => undef, @@ -73,11 +74,13 @@ GetOptions( "check-consolidation" => \$OPTION{consolidation}, "check-disk" => \$OPTION{check_disk_limit}, - "w|warning:f" => \$OPTION{warning}, - "c|critical:f" => \$OPTION{critical}, + "w|warning:s" => \$OPTION{warning}, + "c|critical:s" => \$OPTION{critical}, - "warning2:f" => \$OPTION{warning2}, - "critical2:f" => \$OPTION{critical2}, + "warning2:s" => \$OPTION{warning2}, + "critical2:s" => \$OPTION{critical2}, + + "details-value:s" => \$OPTION{details_value}, "xml" => \$OPTION{xml}, "show-attributes" => \$OPTION{show_attributes}, @@ -131,6 +134,7 @@ sub print_usage () { print " -c (--critical) Critical Threshold (default none)\n"; print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; + print " --details-value Only display VMs with iops higher than the following value (permits to see VMs with high values) (default 50)\n"; print "\n"; print "'datastore-io':\n"; print " --datastore Datastore name to check (required)\n"; @@ -373,6 +377,9 @@ sub datastoreiops_check_arg { if (!defined($OPTION{critical})) { $OPTION{critical} = ''; } + if (!defined($OPTION{details_value})) { + $OPTION{details_value} = 50; + } $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); return 0; @@ -380,7 +387,7 @@ sub datastoreiops_check_arg { sub datastoreiops_get_str { return join($separatorin, - ('datastore-iops', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{skip_errors})); + ('datastore-iops', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{details_value}, $OPTION{skip_errors})); } sub datastoreio_check_arg { @@ -475,7 +482,7 @@ sub datastoreshost_check_arg { sub datastoreshost_get_str { return join($separatorin, - ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical} , $OPTION{datastore}, $OPTION{filter})); + ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical} , $OPTION{datastore})); } sub memhost_check_arg { diff --git a/connectors/vmware/lib/cmddatastoreiops.pm b/connectors/vmware/lib/cmddatastoreiops.pm index ab8a9df78..7f5cf6846 100644 --- a/connectors/vmware/lib/cmddatastoreiops.pm +++ b/connectors/vmware/lib/cmddatastoreiops.pm @@ -23,12 +23,16 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($ds, $warn, $crit) = @_; + my ($ds, $filter, $warn, $crit, $details_value) = @_; if (!defined($ds) || $ds eq "") { $self->{logger}->writeLogError("ARGS error: need datastore name"); return 1; } + if (defined($details_value) && $details_value ne "" && $details_value !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: details-value must be a positive number"); + return 1; + } if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); return 1; @@ -50,14 +54,26 @@ sub initArgs { $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; $self->{warn} = (defined($_[2]) ? $_[2] : ''); $self->{crit} = (defined($_[3]) ? $_[3] : ''); - $self->{skip_errors} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; + $self->{details_value} = (defined($_[4]) ? $_[4] : 50); + $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; } sub run { my $self = shift; + my $status = 0; # OK + my $output = ''; + my $output_append = ''; + my $output_warning = ''; + my $output_warning_append = ''; + my $output_critical = ''; + my $output_critical_append = ''; + my $output_unknown = ''; + my $output_unknown_append = ''; + my $perfdata = ''; + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); + $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); return ; } @@ -79,6 +95,15 @@ sub run { my %disk_name = (); my %datastore_lun = (); foreach (@$result) { + if (!centreon::esxd::common::is_accessible($_->{'summary.accessible'})) { + if ($self->{skip_errors} == 0 || $self->{filter} == 0) { + $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + "'" . $_->{'summary.name'} . "' not accessible. Can be disconnected"); + } + next; + } + if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; # Not need. We are on Datastore level (not LUN level) @@ -93,8 +118,6 @@ sub run { # Zero disk Info #} } - - use Data::Dumper; my @vm_array = (); my %added_vm = (); @@ -108,77 +131,83 @@ sub run { } } - @properties = ('name', 'runtime.connectionState'); + @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); if (!defined($result2)) { return ; } + # Remove disconnected or not running vm my %ref_ids_vm = (); - foreach (@$result2) { - $ref_ids_vm{$_->{mo_ref}->{value}} = $_->{name}; + for(my $i = $#{$result2}; $i >= 0; --$i) { + if (!centreon::esxd::common::is_connected(${$result2}[$i]->{'runtime.connectionState'}->val) || + !centreon::esxd::common::is_running(${$result2}[$i]->{'runtime.powerState'}->val)) { + splice @$result2, $i, 1; + next; + } + $ref_ids_vm{${$result2}[$i]->{mo_ref}->{value}} = ${$result2}[$i]->{name}; } - - print STDERR Data::Dumper::Dumper(%ref_ids_vm); # Vsphere >= 4.1 my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result2, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{obj_esxd}->{perfcounter_speriod}, 1, 1); - print STDERR Data::Dumper::Dumper($values); - return ; + $self->{obj_esxd}->{perfcounter_speriod}, 1, 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - foreach (keys %$values) { - my ($id, $disk_name) = split(/:/); - $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$_}[0]; + my ($vm_id, $id, $disk_name) = split(/:/); + my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{obj_esxd}->{perfcounter_speriod})); + $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; + if (!defined($datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}})) { + $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} = $tmp_value; + } else { + $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; + } } - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $perfdata = ''; + foreach (keys %datastore_lun) { - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); - - if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { + my $total_read_counter = $datastore_lun{$_}{'disk.numberRead.summation'}; + my $total_write_counter = $datastore_lun{$_}{'disk.numberWrite.summation'}; + + if (defined($self->{crit}) && $self->{crit} ne "" && ($total_read_counter >= $self->{crit})) { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $_ . "' is $read_counter ms"); + "'$total_read_counter' read iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberRead.summation', $datastore_lun{$_}, \%ref_ids_vm)); $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($total_read_counter >= $self->{warn})) { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $_ . "' is $read_counter ms"); + "'$total_read_counter' read on '" . $_ . "'" . $self->vm_iops_details('disk.numberRead.summation', $datastore_lun{$_}, \%ref_ids_vm)); $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } - if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { + if (defined($self->{crit}) && $self->{crit} ne "" && ($total_write_counter >= $self->{crit})) { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $_ . "' is $write_counter ms"); + "'$total_write_counter' write iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberWrite.summation', $datastore_lun{$_}, \%ref_ids_vm)); $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { + } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($total_write_counter >= $self->{warn})) { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $_ . "' is $write_counter ms"); + "'$total_write_counter' write iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberWrite.summation', $datastore_lun{$_}, \%ref_ids_vm)); $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } - - $perfdata .= " 'riops_" . $_ . "'=" . $read_counter . "iops 'wiops_" . $_ . "'=" . $write_counter . 'iops'; + + if ($self->{filter} == 1) { + $perfdata .= " 'riops_" . $_ . "'=" . $total_read_counter . "iops;$self->{warn};$self->{crit};0; 'wiops_" . $_ . "'=" . $total_write_counter . "iops;$self->{warn};$self->{crit};0;"; + } else { + $perfdata .= " 'riops=" . $total_read_counter . "iops;$self->{warn};$self->{crit};0; wiops=" . $total_write_counter . "iops;$self->{warn};$self->{crit};0;"; + } } + if ($output_unknown ne "") { + $output .= $output_append . "UNKNOWN - $output_unknown"; + $output_append = ". "; + } if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Datastore IOPS counter: $output_critical"; + $output .= $output_append . "CRITICAL - $output_critical"; $output_append = ". "; } if ($output_warning ne "") { - $output .= $output_append . "WARNING - Datastore IOPS counter: $output_warning"; + $output .= $output_append . "WARNING - $output_warning"; } if ($status == 0) { $output = "All Datastore IOPS counters are ok"; @@ -186,4 +215,19 @@ sub run { $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } +sub vm_iops_details { + my ($self, $label, $ds_details, $ref_ids_vm) = @_; + my $details = ''; + + foreach my $value (keys %$ds_details) { + # Dont need to display vm with iops < 1 + if ($value =~ /^vm.*?$label$/ && $ds_details->{$value} >= $self->{details_value}) { + my ($vm_ids) = split(/_/, $value); + $details .= " ['" . $ref_ids_vm->{$vm_ids} . "' " . $ds_details->{$value} . ']'; + } + } + + return $details; +} + 1; diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/lib/cmddatastoreshost.pm index 26e063d62..042853f73 100644 --- a/connectors/vmware/lib/cmddatastoreshost.pm +++ b/connectors/vmware/lib/cmddatastoreshost.pm @@ -24,7 +24,7 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($lhost, $warn, $crit) = @_; + my ($lhost, $filter, $warn, $crit) = @_; if (!defined($lhost) || $lhost eq "") { $self->{logger}->writeLogError("ARGS error: need host name"); @@ -48,10 +48,10 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lhost} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : ''); - $self->{crit} = (defined($_[2]) ? $_[2] : ''); - $self->{ds} = (defined($_[3]) ? $_[3] : ''); - $self->{filter} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; + $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + $self->{warn} = (defined($_[2]) ? $_[2] : ''); + $self->{crit} = (defined($_[3]) ? $_[3] : ''); + $self->{ds} = (defined($_[4]) ? $_[4] : ''); } sub run { diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/lib/cmddatastoresvm.pm index 13351865a..bab5e88ca 100644 --- a/connectors/vmware/lib/cmddatastoresvm.pm +++ b/connectors/vmware/lib/cmddatastoresvm.pm @@ -129,20 +129,20 @@ sub run { if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $_ . "' is $read_counter ms"); + "read iops on '" . $_ . "' is $read_counter"); $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $_ . "' is $read_counter ms"); + "read iops on '" . $_ . "' is $read_counter"); $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $_ . "' is $write_counter ms"); + "write iops on '" . $_ . "' is $write_counter"); $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $_ . "' is $write_counter ms"); + "write iops '" . $_ . "' is $write_counter"); $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } @@ -150,11 +150,11 @@ sub run { } if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Datastore IOPS counter: $output_critical"; + $output .= $output_append . "CRITICAL - $output_critical"; $output_append = ". "; } if ($output_warning ne "") { - $output .= $output_append . "WARNING - Datastore IOPS counter: $output_warning"; + $output .= $output_append . "WARNING - $output_warning"; } if ($status == 0) { $output = "All Datastore IOPS counters are ok"; From 600cfbc200c0502c4c366e9816534958ddd909ed Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 7 Oct 2013 19:14:39 +0000 Subject: [PATCH 066/447] Some improvements git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@87 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 14 +++++++-- connectors/vmware/lib/cmdcountvmhost.pm | 39 ++++++++++++++++++++---- connectors/vmware/lib/cmdsnapshotvm.pm | 8 +++-- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index ef2eacfbf..f50e5cbd8 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -183,8 +183,10 @@ sub print_usage () { print "\n"; print "'countvmhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold (default none)\n"; - print " -c (--critical) Critical Threshold (default none)\n"; + print " -w (--warning) Warning Threshold if more VMs on (default none)\n"; + print " -c (--critical) Critical Threshold if more VMs on (default none)\n"; + print " --warning2 Warning Threshold if more VMs not on (default none)\n"; + print " --critical2 Critical Threshold if more VMs not on (default none)\n"; print "\n"; print "'uptimehost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -564,12 +566,18 @@ sub countvmhost_check_arg { if (!defined($OPTION{critical})) { $OPTION{critical} = ''; } + if (!defined($OPTION{warning2})) { + $OPTION{warning2} = ''; + } + if (!defined($OPTION{critical2})) { + $OPTION{critical2} = ''; + } return 0; } sub countvmhost_get_str { return join($separatorin, - ('countvmhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); + ('countvmhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); } sub uptimehost_check_arg { diff --git a/connectors/vmware/lib/cmdcountvmhost.pm b/connectors/vmware/lib/cmdcountvmhost.pm index f9f998467..e45182c02 100644 --- a/connectors/vmware/lib/cmdcountvmhost.pm +++ b/connectors/vmware/lib/cmdcountvmhost.pm @@ -23,7 +23,7 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($lhost, $warn, $crit) = @_; + my ($lhost, $warn, $crit, $warn2, $crit2) = @_; if (!defined($lhost) || $lhost eq "") { $self->{logger}->writeLogError("ARGS error: need host name"); @@ -41,6 +41,18 @@ sub checkArgs { $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); return 1; } + if (defined($warn2) && $warn2 ne "" && $warn2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: warn2 threshold must be a positive number"); + return 1; + } + if (defined($crit2) && $crit2 ne "" && $crit2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + $self->{logger}->writeLogError("ARGS error: crit2 threshold must be a positive number"); + return 1; + } + if (defined($warn2) && defined($crit2) && $warn2 ne "" && $crit2 ne "" && $warn2 > $crit2) { + $self->{logger}->writeLogError("ARGS error: warn2 threshold must be lower than crit2 threshold"); + return 1; + } return 0; } @@ -49,6 +61,8 @@ sub initArgs { $self->{lhost} = $_[0]; $self->{warn} = (defined($_[1]) ? $_[1] : ''); $self->{crit} = (defined($_[2]) ? $_[2] : ''); + $self->{warn2} = (defined($_[3]) ? $_[3] : ''); + $self->{crit2} = (defined($_[4]) ? $_[4] : ''); } sub run { @@ -78,25 +92,38 @@ sub run { my $output = ''; my $status = 0; # OK - my $num_poweron = 0; + my $num_poweron = 0; + my $num_powerother = 0; foreach (@$result) { my $power_value = lc($_->{'runtime.powerState'}->val); if ($power_value eq 'poweredon') { $num_poweron++; + } else { + $num_powerother++; } } if (defined($self->{crit}) && $self->{crit} ne "" && ($num_poweron >= $self->{crit})) { - $output = "CRITICAL: $num_poweron VM running."; + $output = "CRITICAL: $num_poweron VM running"; $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($num_poweron >= $self->{warn})) { - $output = "WARNING: $num_poweron VM running."; + $output = "WARNING: $num_poweron VM running"; $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } else { - $output = "OK: $num_poweron VM running."; + $output .= "OK: $num_poweron VM running"; } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|count=$num_poweron\n"); + if (defined($self->{crit2}) && $self->{crit2} ne "" && ($num_powerother >= $self->{crit2})) { + $output .= " - CRITICAL: $num_powerother VM not running."; + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + } elsif (defined($self->{warn2}) && $self->{warn2} ne "" && ($num_powerother >= $self->{warn2})) { + $output .= " - WARNING: $num_powerother VM not running."; + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + } else { + $output .= " - OK: $num_powerother VM not running."; + } + + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|count_on=$num_poweron;$self->{warn};$self->{crit};0; count_not_on=$num_powerother;$self->{warn2};$self->{crit2};0;\n"); } 1; diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm index 45e99f4fb..e3a8c68fa 100644 --- a/connectors/vmware/lib/cmdsnapshotvm.pm +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -94,6 +94,7 @@ sub run { my $output_ok_unit = 'Snapshot(s) OK'; my $consolidate_vms = ''; my $consolidate_vms_append = ''; + my ($num_warning, $num_critical) = (0, 0); foreach my $virtual (@$result) { if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { @@ -133,16 +134,19 @@ sub run { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", "[" . $virtual->{'name'}. "]"); $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $num_critical++; last; } elsif (time() - $create_time >= $self->{warning}) { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", "[" . $virtual->{'name'}. "]"); $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $num_warning++; last; } } } - + + my $perfdata = 'num_warning=' . $num_warning . ' num_critical=' . $num_critical; if ($output_unknown ne "") { $output .= $output_append . "UNKNOWN - $output_unknown"; $output_append = ". "; @@ -166,7 +170,7 @@ sub run { } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; From 933c8d5429d51e000535952d4a7720b275a56c6b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 11 Oct 2013 11:26:08 +0000 Subject: [PATCH 067/447] Fix some minor bugs git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@88 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/lib/cmdnethost.pm | 4 ++-- connectors/vmware/lib/cmdtoolsvm.pm | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index 6e28604e6..fc4343e90 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -144,9 +144,9 @@ sub run { if ($#nic_downs >= 0) { if ($self->{skip_errors} == 0 || $self->{filter} == 0) { $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - } - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", + centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", "Link(s) '" . join("','", @nic_downs) . "' is(are) down"); + } } foreach (keys %pnic_def_up) { diff --git a/connectors/vmware/lib/cmdtoolsvm.pm b/connectors/vmware/lib/cmdtoolsvm.pm index 12f6c51a5..b749f46a2 100644 --- a/connectors/vmware/lib/cmdtoolsvm.pm +++ b/connectors/vmware/lib/cmdtoolsvm.pm @@ -99,9 +99,9 @@ sub run { centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", "VMTools not running on VM:" . $not_running); } - if ($not_running ne '') { + if ($not_up2date ne '') { centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "VMTools not up-to-date on VM:" . $not_running); + "VMTools not up-to-date on VM:" . $not_up2date); } if ($output_unknown ne "") { From 1f3a3465aac53d389bacfd28235cca8e9d9961d1 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 28 Nov 2013 09:58:41 +0000 Subject: [PATCH 068/447] Fix #6269 #6270 git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@89 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esxd-init | 2 +- connectors/vmware/lib/cmdlistnichost.pm | 22 +++++++++++++++++----- connectors/vmware/lib/cmdnethost.pm | 22 +++++++++++++++++----- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/connectors/vmware/centreon_esxd-init b/connectors/vmware/centreon_esxd-init index 501485599..1f36789de 100644 --- a/connectors/vmware/centreon_esxd-init +++ b/connectors/vmware/centreon_esxd-init @@ -19,7 +19,7 @@ timeout=60 pidfile=/var/run/centreon_esxd.pid -[ -e /etc/sysconfig/$servicename ] && . /etc/sysconfig/$servicename +[ -e /etc/sysconfig/centreon_esxd ] && . /etc/sysconfig/centreon_esxd # Check if we can find the binary. if [ ! -x $binary ]; then diff --git a/connectors/vmware/lib/cmdlistnichost.pm b/connectors/vmware/lib/cmdlistnichost.pm index 7c0e94192..e129b188f 100644 --- a/connectors/vmware/lib/cmdlistnichost.pm +++ b/connectors/vmware/lib/cmdlistnichost.pm @@ -49,23 +49,35 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('config.network.pnic', 'config.network.vswitch'); + my @properties = ('config.network.pnic', 'config.network.vswitch', 'config.network.proxySwitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } # Get Name from vswitch - foreach (@{$$result[0]->{'config.network.vswitch'}}) { - foreach my $keynic (@{$_->pnic}) { - $nic_in_vswitch{$keynic} = 1; + if (defined($$result[0]->{'config.network.vswitch'})) { + foreach (@{$$result[0]->{'config.network.vswitch'}}) { + next if (!defined($_->{pnic})); + foreach my $keynic (@{$_->{pnic}}) { + $nic_in_vswitch{$keynic} = 1; + } + } + } + # Get Name from proxySwitch + if (defined($$result[0]->{'config.network.proxySwitch'})) { + foreach (@{$$result[0]->{'config.network.proxySwitch'}}) { + next if (!defined($_->{pnic})); + foreach my $keynic (@{$_->{pnic}}) { + $nic_in_vswitch{$keynic} = 1; + } } } my $status = 0; # OK my $output_up = 'Nic Up List: '; my $output_down = 'Nic Down List: '; - my $output_down_no_vswitch = 'Nic Down List (not in vswitch): '; + my $output_down_no_vswitch = 'Nic Down List (not in vswitch, dvswitch): '; my $output_up_append = ""; my $output_down_append = ""; my $output_down_no_vswitch_append = ""; diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/lib/cmdnethost.pm index fc4343e90..6d1271e4e 100644 --- a/connectors/vmware/lib/cmdnethost.pm +++ b/connectors/vmware/lib/cmdnethost.pm @@ -68,7 +68,7 @@ sub run { } my %filters = ('name' => $self->{lhost}); - my @properties = ('config.network.pnic', 'runtime.connectionState', 'config.network.vswitch'); + my @properties = ('config.network.pnic', 'runtime.connectionState', 'config.network.vswitch', 'config.network.proxySwitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; @@ -84,9 +84,21 @@ sub run { my $filter_ok = 0; # Get Name from vswitch - foreach (@{$$result[0]->{'config.network.vswitch'}}) { - foreach my $keynic (@{$_->pnic}) { - $nic_in_vswitch{$keynic} = 1; + if (defined($$result[0]->{'config.network.vswitch'})) { + foreach (@{$$result[0]->{'config.network.vswitch'}}) { + next if (!defined($_->{pnic})); + foreach my $keynic (@{$_->{pnic}}) { + $nic_in_vswitch{$keynic} = 1; + } + } + } + # Get Name from proxySwitch + if (defined($$result[0]->{'config.network.proxySwitch'})) { + foreach (@{$$result[0]->{'config.network.proxySwitch'}}) { + next if (!defined($_->{pnic})); + foreach my $keynic (@{$_->{pnic}}) { + $nic_in_vswitch{$keynic} = 1; + } } } @@ -111,7 +123,7 @@ sub run { if ($filter_ok == 0) { my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't get physical nic with filter '$self->{pnic}'. (or physical nic not in a vswitch)\n"); + $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't get physical nic with filter '$self->{pnic}'. (or physical nic not in a 'vswitch' or 'dvswitch')\n"); return ; } if ($#${instances} == -1) { From 65506b29f8f5c57201a59291f2e100270b32455e Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 28 Nov 2013 10:05:27 +0000 Subject: [PATCH 069/447] + Update version git-svn-id: http://svn.merethis.net/centreon-esxd/trunk@90 a5eaa968-4c79-4d68-970d-af6011b5b055 --- connectors/vmware/centreon_esx_client.pl | 2 +- connectors/vmware/centreonesxd.pm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index f50e5cbd8..c7315f1d9 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.5.0"; +my $VERSION = "1.5.1"; my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); my $socket; my $separatorin = '~'; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 733e943c5..d141f2b5f 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -20,6 +20,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); +my $VERSION = "1.5.1"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', From d920c1fca94272e38f8d406e0d3fbeed10c36a4e Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 3 Dec 2013 16:36:28 +0100 Subject: [PATCH 070/447] Fix error 'send: Cannot determine peer address' --- connectors/vmware/centreonesxd.pm | 10 ++-------- connectors/vmware/lib/common.pm | 20 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index d141f2b5f..102711a48 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -528,10 +528,7 @@ sub run { $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}; + centreon::esxd::common::response_client2($self, $id, $data_element . "\n"); } else { # Socket my $line = <$rh>; @@ -570,10 +567,7 @@ sub run { 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}->{$_}; + centreon::esxd::common::response_client2($self, $_, "3|TIMEOUT\n"); } } } diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/lib/common.pm index 6a82abd59..c71b749dc 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/lib/common.pm @@ -24,12 +24,28 @@ sub get_status { return $ERRORS{$MYERRORS{$state}}; } +sub response_client2 { + my ($obj_esxd, $id, $msg) = @_; + + # Avoid croak kill. Can be happened (not often) + eval { + ${$obj_esxd->{sockets}->{$id}->{obj}}->send($msg); + }; + $obj_esxd->{read_select}->remove(${$obj_esxd->{sockets}->{$id}->{obj}}); + close ${$obj_esxd->{sockets}->{$id}->{obj}}; + delete $obj_esxd->{sockets}->{$id}; +} + sub response_client1 { my ($obj_esxd, $rh, $current_fileno, $msg) = @_; - $rh->send($msg); - delete $obj_esxd->{sockets}->{$current_fileno}; + + # Avoid croak kill. Can be happened (not often) + eval { + $rh->send($msg); + }; $obj_esxd->{read_select}->remove($rh); close $rh; + delete $obj_esxd->{sockets}->{$current_fileno}; } sub vmware_error { From f31658f54fbf1ce7892e095c4ad9955ac30c9d14 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 3 Dec 2013 17:28:59 +0100 Subject: [PATCH 071/447] Fix an 'isn't numeric in numeric' error --- connectors/vmware/lib/cmdsnapshotvm.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/lib/cmdsnapshotvm.pm index e3a8c68fa..12dec6b35 100644 --- a/connectors/vmware/lib/cmdsnapshotvm.pm +++ b/connectors/vmware/lib/cmdsnapshotvm.pm @@ -111,7 +111,7 @@ sub run { next; } - if ($self->{consolidate} == 1 && defined($virtual->{'runtime.consolidationNeeded'}) && ($virtual->{'runtime.consolidationNeeded'} == 1 || $virtual->{'runtime.consolidationNeeded'} =~ /^true$/i)) { + if ($self->{consolidate} == 1 && defined($virtual->{'runtime.consolidationNeeded'}) && $virtual->{'runtime.consolidationNeeded'} =~ /^true|1$/i) { $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); $consolidate_vms .= $consolidate_vms_append . '[' . $virtual->{'name'} . ']'; $consolidate_vms_append = ', '; From 9b7f88cd2aab2a391c928cee026a7682f618ed48 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 4 Dec 2013 12:15:27 +0100 Subject: [PATCH 072/447] - Fix error from RDM Disk --- connectors/vmware/lib/cmddatastoreiops.pm | 6 ++++++ connectors/vmware/lib/cmddatastoresvm.pm | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/connectors/vmware/lib/cmddatastoreiops.pm b/connectors/vmware/lib/cmddatastoreiops.pm index 7f5cf6846..37eeabd2b 100644 --- a/connectors/vmware/lib/cmddatastoreiops.pm +++ b/connectors/vmware/lib/cmddatastoreiops.pm @@ -159,6 +159,12 @@ sub run { foreach (keys %$values) { my ($vm_id, $id, $disk_name) = split(/:/); + + # RDM Disk. We skip. Don't know how to manage it right now. + if (!defined($disk_name{$disk_name})) { + next; + } + my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{obj_esxd}->{perfcounter_speriod})); $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; if (!defined($datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}})) { diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/lib/cmddatastoresvm.pm index bab5e88ca..a5aba1c87 100644 --- a/connectors/vmware/lib/cmddatastoresvm.pm +++ b/connectors/vmware/lib/cmddatastoresvm.pm @@ -112,6 +112,12 @@ sub run { foreach (keys %$values) { my ($id, $disk_name) = split(/:/); + + # RDM Disk. We skip. Don't know how to manage it right now. + if (!defined($disk_name{$disk_name})) { + next; + } + $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$_}[0]; } From 68271b1d35177036fd7eb731302671e36df81612 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 4 Dec 2013 12:24:46 +0100 Subject: [PATCH 073/447] + Add version number --- connectors/vmware/centreon_esx_client.pl | 2 +- connectors/vmware/centreonesxd.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index c7315f1d9..2006ce79c 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.5.1"; +my $VERSION = "1.5.2"; my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); my $socket; my $separatorin = '~'; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 102711a48..798e6e582 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -20,7 +20,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); -my $VERSION = "1.5.1"; +my $VERSION = "1.5.2"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', From ad11cdd3b886c4e4a88cd971f4b1609effb86681 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 6 Dec 2013 12:36:02 +0100 Subject: [PATCH 074/447] Fix #6309 --- connectors/vmware/centreon_esx_client.pl | 17 +++++++++++------ connectors/vmware/centreonesxd.pm | 2 +- connectors/vmware/lib/cmdlistdatastore.pm | 6 ------ connectors/vmware/lib/cmdlistnichost.pm | 6 ------ 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 2006ce79c..e39d0092a 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.5.2"; +my $VERSION = "1.5.3"; my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); my $socket; my $separatorin = '~'; @@ -66,7 +66,6 @@ GetOptions( "nic=s" => \$OPTION{nic}, - "older=i" => \$OPTION{older}, "warn" => \$OPTION{warn}, "crit" => \$OPTION{crit}, @@ -772,30 +771,36 @@ sub listhost_get_str { } sub listdatastore_check_arg { + if (defined($OPTION{show_attributes})) { + print "name\n"; + } $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); - $OPTION{show_attributes} = (defined($OPTION{show_attributes}) ? 1 : 0); return 0; } sub listdatastore_get_str { return join($separatorin, - ('listdatastore', $OPTION{vsphere}, $OPTION{xml}, $OPTION{show_attributes})); + ('listdatastore', $OPTION{vsphere}, $OPTION{xml})); } sub listnichost_check_arg { + if (defined($OPTION{show_attributes})) { + print "name\n"; + exit(0); + } + if (!defined($OPTION{'esx-host'})) { print "Option --esx-host is required\n"; print_usage(); exit $ERRORS{UNKNOWN}; } $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); - $OPTION{show_attributes} = (defined($OPTION{show_attributes}) ? 1 : 0); return 0; } sub listnichost_get_str { return join($separatorin, - ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{xml}, $OPTION{show_attributes})); + ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{xml})); } sub getmap_check_arg { diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 798e6e582..2818c24b4 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -20,7 +20,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); -my $VERSION = "1.5.2"; +my $VERSION = "1.5.3"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', diff --git a/connectors/vmware/lib/cmdlistdatastore.pm b/connectors/vmware/lib/cmdlistdatastore.pm index 6a470d5b6..959e9d013 100644 --- a/connectors/vmware/lib/cmdlistdatastore.pm +++ b/connectors/vmware/lib/cmdlistdatastore.pm @@ -29,17 +29,11 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{xml} = (defined($_[0]) && $_[0] == 1) ? 1 : 0; - $self->{show_attributes} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; } sub run { my $self = shift; - if ($self->{show_attributes} == 1) { - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status(0) . "|name\n"); - return ; - } - my %filters = (); my @properties = ('summary'); diff --git a/connectors/vmware/lib/cmdlistnichost.pm b/connectors/vmware/lib/cmdlistnichost.pm index e129b188f..f41269b80 100644 --- a/connectors/vmware/lib/cmdlistnichost.pm +++ b/connectors/vmware/lib/cmdlistnichost.pm @@ -36,17 +36,11 @@ sub initArgs { my $self = shift; $self->{lhost} = $_[0]; $self->{xml} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{show_attributes} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; } sub run { my $self = shift; my %nic_in_vswitch = (); - - if ($self->{show_attributes} == 1) { - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status(0) . "|name\n"); - return ; - } my %filters = ('name' => $self->{lhost}); my @properties = ('config.network.pnic', 'config.network.vswitch', 'config.network.proxySwitch'); From 22ab7eac2c1bd9fa559e6599f9af88042e715872 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 6 Dec 2013 14:39:56 +0100 Subject: [PATCH 075/447] + Fix error --- connectors/vmware/centreon_esx_client.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index e39d0092a..0be2faa79 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -773,6 +773,7 @@ sub listhost_get_str { sub listdatastore_check_arg { if (defined($OPTION{show_attributes})) { print "name\n"; + exit(0); } $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); return 0; From 749469094d871e022f2c31176140bfb43f03e945 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 6 Mar 2014 15:45:03 +0100 Subject: [PATCH 076/447] Fix credstore issue to use it --- connectors/vmware/centreonesxd.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 2818c24b4..fc2b265a6 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -136,8 +136,8 @@ sub init { $self->load_module(@load_modules); ##### credstore check ##### - if (defined($self->{credstore_use}) && defined($self->{credstore_file}) && - $self->{credstore_use} == 1 && -e "$self->{credstore_file}") { + if (defined($self->{centreonesxd_config}->{credstore_use}) && defined($self->{centreonesxd_config}->{credstore_file}) && + $self->{centreonesxd_config}->{credstore_use} == 1 && -e "$self->{centreonesxd_config}->{credstore_file}") { eval 'require VMware::VICredStore'; if ($@) { $self->{logger}->writeLogError("Could not load module VMware::VICredStore"); @@ -145,7 +145,7 @@ sub init { } require VMware::VICredStore; - if (VMware::VICredStore::init(filename => $self->{credstore_file}) == 0) { + if (VMware::VICredStore::init(filename => $self->{centreonesxd_config}->{credstore_file}) == 0) { $self->{logger}->writeLogError("Credstore init failed: $@"); exit(1); } From d805a367371c1a982a4eaacaec528fd20a8bda5d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 19 Mar 2014 11:53:40 +0100 Subject: [PATCH 077/447] Fix #6754 --- connectors/vmware/centreonesxd.pm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index fc2b265a6..6caf7becc 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -481,6 +481,11 @@ sub run { while (1) { my @rh_set = $self->{read_select}->can_read(15); if ($self->{stop} == 1) { + # No childs + if (scalar(keys %{$self->{centreonesxd_config}->{vsphere_server}}) == 0) { + $self->{logger}->writeLogInfo("Quit main process"); + exit(0); + } 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}; @@ -496,7 +501,7 @@ sub run { $client = $rh->accept(); $client->autoflush(1); $self->{counter}++; - $self->{sockets}->{fileno($client)} = {"obj" => \$client, "ctime" => time(), "counter" => $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})) { From de07f2d3f74dc4139f3deb4e5222cb3c4b95f665 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 19 Mar 2014 14:54:15 +0100 Subject: [PATCH 078/447] Fix #6623 --- .../vmware/doc-en/exploitation/index.rst | 1338 +---------------- .../vmware/doc-en/installation/index.rst | 124 +- connectors/vmware/doc/exploitation/index.rst | 1324 +--------------- connectors/vmware/doc/installation/index.rst | 139 +- 4 files changed, 203 insertions(+), 2722 deletions(-) diff --git a/connectors/vmware/doc-en/exploitation/index.rst b/connectors/vmware/doc-en/exploitation/index.rst index d3b1d098b..c0db0f76e 100644 --- a/connectors/vmware/doc-en/exploitation/index.rst +++ b/connectors/vmware/doc-en/exploitation/index.rst @@ -2,11 +2,8 @@ Exploitation ============ -Centreon-esxd Presentation ---------------------------- - Generals Principles -``````````````````` +------------------- Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter. @@ -29,1338 +26,27 @@ Steps of operation : Then, this process gets back the VMWare indicators creating a subprocess per request. Centreon-esxd necessitates the utilization of one (or more) VirtualCenter (or ESX). -This is a example of a fragmented architecture : +This is a example of a distributed architecture : .. image:: ../images/archi.png Operating mode -`````````````` -The "centreon-esxd" program only works in "daemon" mode. (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). +-------------- -Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. +The "centreon-esxd" program only works in "daemon" mode (a client is needed). + +Connector configuration +----------------------- -Configuration du connecteur -``````````````````````````` Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - $centreonesxd_config = { + %centreonesxd_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', - 'username' => 'qgarnier@merethis.net', - 'password' => 'XXXXXX'} + 'username' => 'test@test.fr', + 'password' => 'xxxx'}, } - port => 5700 - }; - -L'attribut «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. - -L'attribut « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». - -Optimisation de la configuration dans Centreon ----------------------------------------------- - -Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. - -Ce connecteur permet la définition de trois modèles d'hôtes : - -- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. -- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. -- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») - -Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. - -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | -| | | | -+====================+===================================================================+================================================================+ -| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ - -Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». - - -Création d'un modèle d'hôte VMWare générique -```````````````````````````````````````````` - -Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». - -Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. - -Définir les macros suivante : - -+---------------------+-------------------------------------------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+===================================================================+ -| ESXDHOST | Exemple: 10.30.10.30 | -+---------------------+-------------------------------------------------------------------+ -| ESXDPORT | 5700 (port par défaut) | -+---------------------+-------------------------------------------------------------------+ -| VCNAME | default | -+---------------------+-------------------------------------------------------------------+ - -Troubleshooting -``````````````` - -Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: - - ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... - -Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. - -Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. - - -Liste des contrôles -------------------- - -Contrôles ESX -````````````` -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+===========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuhost | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | -| | - le taux d'utilisation mémoire (en octets), | -| | - la taille totale de la mémoire (en octets), | -| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memhost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -RESEAU -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_nethost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux d'utilisation en entrée et sortie (en b/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | nethost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| NICNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -SWAP -'''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_swaphost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | swaphost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 0.8 | -+---------------------+--------------------------------+ -| CRITICAL | 1 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreshost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | -| | - la latence totale en lecture et écriture (en ms). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+============================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoreshost | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 30 | -+---------------------+--------------------------------+ -| CRITICAL | 50 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -COUNTVM -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_countvmhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | -| | - le nombre de machines virtuelles allumées. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | count=45 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | countvmhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 10 | -+---------------------+--------------------------------+ -| CRITICAL | 15 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -HEALTH -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_healthhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | Remonte un état selon l'état des sondes: | -| | - "Yellow" correspond à WARNING. | -| | - "Red" correspond à CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | healthhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MAINTENANCE -''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_maintenancehost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | maintenancehost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -STATUT -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_statushost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état global d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | -| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | -| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | statushost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôles d'une machine virtuelle -````````````````````````````````` - -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuvm | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | -| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | -| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | -| | - « overhead » : la mémoire sur-alloué (en octets) | -| | - « ballooning », « shared » et « active ». | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoresvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | -| | - « riops » : le nombre moyen d'I/O de lectures par seconde | -| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoresvm | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -VMTOOLS -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_toolsvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | -| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | toolsvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -SNAPSHOTS -''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_snapshotvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | L'état dépend des paramètres du plugin : | -| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | -| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | -| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+====================+==========================================================================================+================================================================+ -| -u | Indicateur à contrôler | snapshotvm | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| THRESHOLD | - -warn | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôle d'un datastore -``````````````````````` - -USAGE -''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreusage | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | -| | - « used » : l'espace occupé par le datastore (en octets) | -| | - « size » : la taille totale allouée pour le datastore (en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-usage | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORE I/O -''''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastorio | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | -| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | -| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-io | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. + ); +« vsphere_server » attribute configure VirtualCenter access. diff --git a/connectors/vmware/doc-en/installation/index.rst b/connectors/vmware/doc-en/installation/index.rst index 9fae9d636..cac06bda4 100644 --- a/connectors/vmware/doc-en/installation/index.rst +++ b/connectors/vmware/doc-en/installation/index.rst @@ -8,25 +8,24 @@ Prerequisites Software Recommandations ```````````````````````` -The "centreon-esxd" connector has been tested on linux systems. -Installation on other system is possible but is outside the scope of this document. +The "centreon-esxd" connector has been tested on red-hat 5 and 6 with rpms. +Installation on other system is possible but is outside the scope of this document (Debian,...). -==================== ===================== -Software Minimal Version -==================== ===================== +==================== ===================== +Software Version +==================== ===================== VMWare SDK Perl 5.1 Perl 5.8 centreon-esxd 1.4 centreon-common-perl 2.5 -==================== ===================== +==================== ===================== Hardware Recommandations ```````````````````````` -Hardware prerequisites will vary depending on the number of monitored hosts. Without configured, no checks are done. Minimal used ressources are : +Hardware prerequisites will depend of check numbers. Minimal used ressources are : * RAM : 512 Mo (May slightly increase with the number of checks). - * CPU : same as poller server. Centreon-esxd Installation - centos/rhel 5 systems @@ -35,46 +34,43 @@ Centreon-esxd Installation - centos/rhel 5 systems SDK Perl VMWare Installation ```````````````````````````` -The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. +The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommandation (only tested with version below). -Install CPAN prerequisites :: +======================= ===================== ====================== +Dependency Version Repository +======================= ===================== ====================== +perl-libwww-perl 5.805 redhat/centos base +perl-XML-LibXML 1.58 redhat/centos base +perl-Class-MethodMaker 2.18 ces base +perl-Crypt-SSLeay 0.51 redhat/centos base +perl-SOAP-Lite 0.712 ces base +perl-UUID 0.04 ces base +perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs +======================= ===================== ====================== - root # yum install gcc make unzip wget e2fsprogs-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-libwww-perl perl-TimeDate - - root # cpan install Class::MethodMaker - root # cpan install SOAP::Lite - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install +Install following dependency:: -All SDK prerequisites are installed. - -Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) - -Install VMWare Perl SDK:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install + root # yum install perl-VMware-vSphere Requirements ``````````````````````````````` -« centreon-common-perl » is a prerequisite for « centreon_esxd ». (Module in Centreon 2.5) +« perl-centreon-base » is a prerequisite for « centreon_esxd ». (Module in Centreon 2.5) +centreon-esxd Installation with rpm +``````````````````````````````````` -centreon-esxd Installation -`````````````````````````` +Install the connector:: + + root # yum install ces-plugins-Virtualization-VMWare + +centreon-esxd Installation with source +`````````````````````````````````````` Download « centreon-esxd » archive, then install :: - root # tar zxvf centreon-esxd-1.4.tar.gz - root # cd centreon-esxd-1.4 + root # tar zxvf centreon-esxd-1.5.4.tar.gz + root # cd centreon-esxd-1.5.4 root # cp centreon_esxd /usr/bin/ root # mkdir -p /etc/centreon @@ -89,13 +85,63 @@ Configure "centreon-esxd" daemon to start at boot :: root # chkconfig --level 2345 centreon_esxd on - *"centreon_esx_client.pl" is the corresponding nagios plugin.* Centreon-esxd Installation - centos/rhel 6 systems ================================================== SDK Perl VMWare Installation -````````````````````````````` +```````````````````````````` -TODO \ No newline at end of file +The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommandation (only tested with version below). + +======================= ===================== ====================== +Dependency Version Repository +======================= ===================== ====================== +perl-libwww-perl 5.833 redhat/centos base +perl-XML-LibXML 1.70 redhat/centos base +perl-Class-MethodMaker 2.16 redhat/centos base +perl-Crypt-SSLeay 0.57 redhat/centos base +perl-SOAP-Lite 0.710.10 redhat/centos base +perl-UUID 0.04 centreon plugin-packs +perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs +======================= ===================== ====================== + +Install following dependency:: + + root # yum install perl-VMware-vSphere + +Requirements +``````````````````````````````` + +« perl-centreon-base » is a prerequisite for « centreon_esxd ». (Module in Centreon 2.5) + +centreon-esxd Installation with rpm +``````````````````````````````````` + +Install the connector:: + + root # yum install ces-plugins-Virtualization-VMWare + +centreon-esxd Installation with source +`````````````````````````````````````` + +Download « centreon-esxd » archive, then install :: + + root # tar zxvf centreon-esxd-1.5.4.tar.gz + root # cd centreon-esxd-1.5.4 + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp lib/* /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + +Configure "centreon-esxd" daemon to start at boot :: + + root # chkconfig --level 2345 centreon_esxd on + +*"centreon_esx_client.pl" is the corresponding nagios plugin.* \ No newline at end of file diff --git a/connectors/vmware/doc/exploitation/index.rst b/connectors/vmware/doc/exploitation/index.rst index 67bd6edf3..a8ffa66ef 100644 --- a/connectors/vmware/doc/exploitation/index.rst +++ b/connectors/vmware/doc/exploitation/index.rst @@ -2,11 +2,8 @@ Exploitation ============ -Présentation de Centreon-esxd ------------------------------ - Principes Généraux -`````````````````` +------------------ Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. @@ -35,1333 +32,36 @@ Voici un exemple d'architecture éclaté : .. image:: ../images/archi.png Mode de fonctionnement -`````````````````````` +---------------------- + Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). -Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. - Configuration du connecteur -``````````````````````````` +--------------------------- + Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - $centreonesxd_config = { + %centreonesxd_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', - 'username' => 'qgarnier@merethis.net', - 'password' => 'XXXXXX'} + 'username' => 'test@test.fr', + 'password' => 'xxxx'}, } - port => 5700 - }; + ); -L'attribut «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. - -L'attribut « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». - -Optimisation de la configuration dans Centreon ----------------------------------------------- - -Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. - -Ce connecteur permet la définition de trois modèles d'hôtes : - -- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. -- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. -- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») - -Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. - -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | -| | | | -+====================+===================================================================+================================================================+ -| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ - -Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». - - -Création d'un modèle d'hôte VMWare générique -```````````````````````````````````````````` - -Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». - -Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. - -Définir les macros suivante : - -+---------------------+-------------------------------------------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+===================================================================+ -| ESXDHOST | Exemple: 10.30.10.30 | -+---------------------+-------------------------------------------------------------------+ -| ESXDPORT | 5700 (port par défaut) | -+---------------------+-------------------------------------------------------------------+ -| VCNAME | default | -+---------------------+-------------------------------------------------------------------+ +L'attribut « vsphere_server » permet de configurer les accès aux différents VirtualCenter. Troubleshooting -``````````````` +--------------- Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: - ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... + ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. -Liste des contrôles -------------------- - -Contrôles ESX -````````````` -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+===========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuhost | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | -| | - le taux d'utilisation mémoire (en octets), | -| | - la taille totale de la mémoire (en octets), | -| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memhost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -RESEAU -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_nethost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux d'utilisation en entrée et sortie (en b/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | nethost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| NICNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -SWAP -'''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_swaphost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | swaphost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 0.8 | -+---------------------+--------------------------------+ -| CRITICAL | 1 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreshost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | -| | - la latence totale en lecture et écriture (en ms). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+============================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoreshost | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 30 | -+---------------------+--------------------------------+ -| CRITICAL | 50 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -COUNTVM -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_countvmhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | -| | - le nombre de machines virtuelles allumées. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | count=45 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | countvmhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 10 | -+---------------------+--------------------------------+ -| CRITICAL | 15 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -HEALTH -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_healthhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | Remonte un état selon l'état des sondes: | -| | - "Yellow" correspond à WARNING. | -| | - "Red" correspond à CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | healthhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MAINTENANCE -''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_maintenancehost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | maintenancehost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -STATUT -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_statushost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état global d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | -| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | -| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | statushost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôles d'une machine virtuelle -````````````````````````````````` - -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuvm | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | -| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | -| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | -| | - « overhead » : la mémoire sur-alloué (en octets) | -| | - « ballooning », « shared » et « active ». | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoresvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | -| | - « riops » : le nombre moyen d'I/O de lectures par seconde | -| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoresvm | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -VMTOOLS -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_toolsvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | -| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | toolsvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -SNAPSHOTS -''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_snapshotvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | L'état dépend des paramètres du plugin : | -| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | -| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | -| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+====================+==========================================================================================+================================================================+ -| -u | Indicateur à contrôler | snapshotvm | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| THRESHOLD | - -warn | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôle d'un datastore -``````````````````````` - -USAGE -''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreusage | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | -| | - « used » : l'espace occupé par le datastore (en octets) | -| | - « size » : la taille totale allouée pour le datastore (en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-usage | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORE I/O -''''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastorio | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | -| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | -| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-io | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. diff --git a/connectors/vmware/doc/installation/index.rst b/connectors/vmware/doc/installation/index.rst index 547c0120a..73912e6a5 100644 --- a/connectors/vmware/doc/installation/index.rst +++ b/connectors/vmware/doc/installation/index.rst @@ -8,17 +8,17 @@ Pré-Requis Préconisations logicielles `````````````````````````` -Le connecteur "centreon-esxd" est testé et validé sur des environnements Linux. -L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Solaris, Windows, ...). +Le connecteur "centreon-esxd" est testé et validé sur red-hat 5 et 6 avec des rpms. +L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Debian, ...). -==================== ===================== -Logiciels Version minimum -==================== ===================== -VMWare SDK Perl 5.1 -Perl 5.8 -centreon-esxd 1.4 -centreon-common-perl 2.5 -==================== ===================== +==================== ===================== +Logiciels Version +==================== ===================== +VMWare SDK Perl 5.1.0-780721 +Perl 5.8 +centreon-esxd 1.5.4 +perl-centreon-base 2.5.0 +==================== ===================== Préconisations matérielles `````````````````````````` @@ -26,7 +26,6 @@ Préconisations matérielles Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n'effectue aucunes vérifications. Les ressources minimales sont de : * mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). - * CPU : même pré-requis que pour le serveur de collecte. Installation de centreon-esxd - Environnement centos/rhel 5 @@ -35,70 +34,120 @@ Installation de centreon-esxd - Environnement centos/rhel 5 Installation du SDK Perl VMWare ``````````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). -Installer les pré-requis CPAN:: +======================= ===================== ====================== +Dépendance Version Dépôt +======================= ===================== ====================== +perl-libwww-perl 5.805 redhat/centos base +perl-XML-LibXML 1.58 redhat/centos base +perl-Class-MethodMaker 2.18 ces base +perl-Crypt-SSLeay 0.51 redhat/centos base +perl-SOAP-Lite 0.712 ces base +perl-UUID 0.04 ces base +perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs +======================= ===================== ====================== - root # yum install gcc make unzip wget e2fsprogs-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-libwww-perl perl-TimeDate - - root # cpan install Class::MethodMaker - root # cpan install SOAP::Lite - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install +Installer la dépendance suivante:: -Nous avons notre environnement prêt pour l'installation du SDK VMWare. - -Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_). - -Installer le SDK Perl VMWare:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install + root # yum install perl-VMware-vSphere Pré-requis ``````````````````````````````````````` -« centreon-common-perl » est nécessaire pour le fonctionnement de « centreon_esxd ». Ce module est présent à partir de Centreon 2.5. +« perl-centreon-base » est nécessaire pour le fonctionnement de « centreon_esxd ». Ce module est présent à partir de Centreon 2.5. -Installation de centreon-esxd -````````````````````````````` +Installation de centreon-esxd par rpm +````````````````````````````````````` + +Installer le connecteur:: + + root # yum install ces-plugins-Virtualization-VMWare + +Installation de centreon-esxd par les sources +````````````````````````````````````````````` Télécharger l'archive de « centreon-esxd ». Installer les fichiers:: - root # tar zxvf centreon-esxd-1.4.tar.gz - root # cd centreon-esxd-1.4 + root # tar zxvf centreon-esxd-1.5.4.tar.gz + root # cd centreon-esxd-1.5.4 root # cp centreon_esxd /usr/bin/ root # mkdir -p /etc/centreon root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm root # cp centreon_esxd-init /etc/init.d/centreon_esxd - root # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/ - root # cp lib/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/ - root # cp centreonesxd.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ + root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp lib/* /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ Activer le daemon « centreon-esxd » au démarrage:: root # chkconfig --level 2345 centreon_esxd on - *Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* Installation de centreon-esxd - Environnement centos/rhel 6 =========================================================== -Installation du sdk Perl VMWare +Installation du SDK Perl VMWare ``````````````````````````````` -TODO +Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). + +======================= ===================== ====================== +Dépendance Version Dépôt +======================= ===================== ====================== +perl-libwww-perl 5.833 redhat/centos base +perl-XML-LibXML 1.70 redhat/centos base +perl-Class-MethodMaker 2.16 redhat/centos base +perl-Crypt-SSLeay 0.57 redhat/centos base +perl-SOAP-Lite 0.710.10 redhat/centos base +perl-UUID 0.04 centreon plugin-packs +perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs +======================= ===================== ====================== + +Installer la dépendance suivante:: + + root # yum install perl-VMware-vSphere + +Pré-requis +``````````````````````````````````````` + +« perl-centreon-base » est nécessaire pour le fonctionnement de « centreon_esxd ». Ce module est présent à partir de Centreon 2.5. + +Installation de centreon-esxd par rpm +````````````````````````````````````` + +Installer le connecteur:: + + root # yum install ces-plugins-Virtualization-VMWare + +Installation de centreon-esxd par les sources +````````````````````````````````````````````` + +Télécharger l'archive de « centreon-esxd ». + +Installer les fichiers:: + + root # tar zxvf centreon-esxd-1.5.4.tar.gz + root # cd centreon-esxd-1.5.4 + root # cp centreon_esxd /usr/bin/ + + root # mkdir -p /etc/centreon + root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm + root # cp centreon_esxd-init /etc/init.d/centreon_esxd + + root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp lib/* /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + +Activer le daemon « centreon-esxd » au démarrage:: + + root # chkconfig --level 2345 centreon_esxd on + +*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* From 5bf71612d60af44234569b0630034430f2ccb66b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 19 Mar 2014 14:54:47 +0100 Subject: [PATCH 079/447] Change fr name --- connectors/vmware/{doc => doc-fr}/Makefile | 0 .../_build/doctrees/environment.pickle | Bin .../_build/doctrees/exploitation/index.doctree | Bin .../{doc => doc-fr}/_build/doctrees/index.doctree | Bin .../_build/doctrees/installation/index.doctree | Bin .../vmware/{doc => doc-fr}/_build/html/.buildinfo | 0 .../{doc => doc-fr}/_build/html/_images/archi.png | Bin .../_build/html/_sources/exploitation/index.txt | 0 .../{doc => doc-fr}/_build/html/_sources/index.txt | 0 .../_build/html/_sources/installation/index.txt | 0 .../_build/html/_static/ajax-loader.gif | Bin .../{doc => doc-fr}/_build/html/_static/basic.css | 0 .../_build/html/_static/comment-bright.png | Bin .../_build/html/_static/comment-close.png | Bin .../{doc => doc-fr}/_build/html/_static/comment.png | Bin .../{doc => doc-fr}/_build/html/_static/default.css | 0 .../{doc => doc-fr}/_build/html/_static/doctools.js | 0 .../_build/html/_static/down-pressed.png | Bin .../{doc => doc-fr}/_build/html/_static/down.png | Bin .../{doc => doc-fr}/_build/html/_static/file.png | Bin .../{doc => doc-fr}/_build/html/_static/jquery.js | 0 .../{doc => doc-fr}/_build/html/_static/minus.png | Bin .../{doc => doc-fr}/_build/html/_static/plus.png | Bin .../_build/html/_static/pygments.css | 0 .../_build/html/_static/searchtools.js | 0 .../{doc => doc-fr}/_build/html/_static/sidebar.js | 0 .../_build/html/_static/underscore.js | 0 .../_build/html/_static/up-pressed.png | Bin .../{doc => doc-fr}/_build/html/_static/up.png | Bin .../_build/html/_static/websupport.js | 0 .../_build/html/exploitation/index.html | 0 .../{doc => doc-fr}/_build/html/genindex.html | 0 .../vmware/{doc => doc-fr}/_build/html/index.html | 0 .../_build/html/installation/index.html | 0 .../vmware/{doc => doc-fr}/_build/html/objects.inv | Bin .../vmware/{doc => doc-fr}/_build/html/search.html | 0 .../{doc => doc-fr}/_build/html/searchindex.js | 0 connectors/vmware/{doc => doc-fr}/conf.py | 0 .../vmware/{doc => doc-fr}/exploitation/index.rst | 0 connectors/vmware/{doc => doc-fr}/images/archi.png | Bin connectors/vmware/{doc => doc-fr}/index.rst | 0 .../vmware/{doc => doc-fr}/installation/index.rst | 0 42 files changed, 0 insertions(+), 0 deletions(-) rename connectors/vmware/{doc => doc-fr}/Makefile (100%) rename connectors/vmware/{doc => doc-fr}/_build/doctrees/environment.pickle (100%) rename connectors/vmware/{doc => doc-fr}/_build/doctrees/exploitation/index.doctree (100%) rename connectors/vmware/{doc => doc-fr}/_build/doctrees/index.doctree (100%) rename connectors/vmware/{doc => doc-fr}/_build/doctrees/installation/index.doctree (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/.buildinfo (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_images/archi.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_sources/exploitation/index.txt (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_sources/index.txt (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_sources/installation/index.txt (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/ajax-loader.gif (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/basic.css (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/comment-bright.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/comment-close.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/comment.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/default.css (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/doctools.js (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/down-pressed.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/down.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/file.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/jquery.js (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/minus.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/plus.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/pygments.css (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/searchtools.js (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/sidebar.js (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/underscore.js (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/up-pressed.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/up.png (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/_static/websupport.js (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/exploitation/index.html (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/genindex.html (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/index.html (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/installation/index.html (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/objects.inv (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/search.html (100%) rename connectors/vmware/{doc => doc-fr}/_build/html/searchindex.js (100%) rename connectors/vmware/{doc => doc-fr}/conf.py (100%) rename connectors/vmware/{doc => doc-fr}/exploitation/index.rst (100%) rename connectors/vmware/{doc => doc-fr}/images/archi.png (100%) rename connectors/vmware/{doc => doc-fr}/index.rst (100%) rename connectors/vmware/{doc => doc-fr}/installation/index.rst (100%) diff --git a/connectors/vmware/doc/Makefile b/connectors/vmware/doc-fr/Makefile similarity index 100% rename from connectors/vmware/doc/Makefile rename to connectors/vmware/doc-fr/Makefile diff --git a/connectors/vmware/doc/_build/doctrees/environment.pickle b/connectors/vmware/doc-fr/_build/doctrees/environment.pickle similarity index 100% rename from connectors/vmware/doc/_build/doctrees/environment.pickle rename to connectors/vmware/doc-fr/_build/doctrees/environment.pickle diff --git a/connectors/vmware/doc/_build/doctrees/exploitation/index.doctree b/connectors/vmware/doc-fr/_build/doctrees/exploitation/index.doctree similarity index 100% rename from connectors/vmware/doc/_build/doctrees/exploitation/index.doctree rename to connectors/vmware/doc-fr/_build/doctrees/exploitation/index.doctree diff --git a/connectors/vmware/doc/_build/doctrees/index.doctree b/connectors/vmware/doc-fr/_build/doctrees/index.doctree similarity index 100% rename from connectors/vmware/doc/_build/doctrees/index.doctree rename to connectors/vmware/doc-fr/_build/doctrees/index.doctree diff --git a/connectors/vmware/doc/_build/doctrees/installation/index.doctree b/connectors/vmware/doc-fr/_build/doctrees/installation/index.doctree similarity index 100% rename from connectors/vmware/doc/_build/doctrees/installation/index.doctree rename to connectors/vmware/doc-fr/_build/doctrees/installation/index.doctree diff --git a/connectors/vmware/doc/_build/html/.buildinfo b/connectors/vmware/doc-fr/_build/html/.buildinfo similarity index 100% rename from connectors/vmware/doc/_build/html/.buildinfo rename to connectors/vmware/doc-fr/_build/html/.buildinfo diff --git a/connectors/vmware/doc/_build/html/_images/archi.png b/connectors/vmware/doc-fr/_build/html/_images/archi.png similarity index 100% rename from connectors/vmware/doc/_build/html/_images/archi.png rename to connectors/vmware/doc-fr/_build/html/_images/archi.png diff --git a/connectors/vmware/doc/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc-fr/_build/html/_sources/exploitation/index.txt similarity index 100% rename from connectors/vmware/doc/_build/html/_sources/exploitation/index.txt rename to connectors/vmware/doc-fr/_build/html/_sources/exploitation/index.txt diff --git a/connectors/vmware/doc/_build/html/_sources/index.txt b/connectors/vmware/doc-fr/_build/html/_sources/index.txt similarity index 100% rename from connectors/vmware/doc/_build/html/_sources/index.txt rename to connectors/vmware/doc-fr/_build/html/_sources/index.txt diff --git a/connectors/vmware/doc/_build/html/_sources/installation/index.txt b/connectors/vmware/doc-fr/_build/html/_sources/installation/index.txt similarity index 100% rename from connectors/vmware/doc/_build/html/_sources/installation/index.txt rename to connectors/vmware/doc-fr/_build/html/_sources/installation/index.txt diff --git a/connectors/vmware/doc/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc-fr/_build/html/_static/ajax-loader.gif similarity index 100% rename from connectors/vmware/doc/_build/html/_static/ajax-loader.gif rename to connectors/vmware/doc-fr/_build/html/_static/ajax-loader.gif diff --git a/connectors/vmware/doc/_build/html/_static/basic.css b/connectors/vmware/doc-fr/_build/html/_static/basic.css similarity index 100% rename from connectors/vmware/doc/_build/html/_static/basic.css rename to connectors/vmware/doc-fr/_build/html/_static/basic.css diff --git a/connectors/vmware/doc/_build/html/_static/comment-bright.png b/connectors/vmware/doc-fr/_build/html/_static/comment-bright.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/comment-bright.png rename to connectors/vmware/doc-fr/_build/html/_static/comment-bright.png diff --git a/connectors/vmware/doc/_build/html/_static/comment-close.png b/connectors/vmware/doc-fr/_build/html/_static/comment-close.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/comment-close.png rename to connectors/vmware/doc-fr/_build/html/_static/comment-close.png diff --git a/connectors/vmware/doc/_build/html/_static/comment.png b/connectors/vmware/doc-fr/_build/html/_static/comment.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/comment.png rename to connectors/vmware/doc-fr/_build/html/_static/comment.png diff --git a/connectors/vmware/doc/_build/html/_static/default.css b/connectors/vmware/doc-fr/_build/html/_static/default.css similarity index 100% rename from connectors/vmware/doc/_build/html/_static/default.css rename to connectors/vmware/doc-fr/_build/html/_static/default.css diff --git a/connectors/vmware/doc/_build/html/_static/doctools.js b/connectors/vmware/doc-fr/_build/html/_static/doctools.js similarity index 100% rename from connectors/vmware/doc/_build/html/_static/doctools.js rename to connectors/vmware/doc-fr/_build/html/_static/doctools.js diff --git a/connectors/vmware/doc/_build/html/_static/down-pressed.png b/connectors/vmware/doc-fr/_build/html/_static/down-pressed.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/down-pressed.png rename to connectors/vmware/doc-fr/_build/html/_static/down-pressed.png diff --git a/connectors/vmware/doc/_build/html/_static/down.png b/connectors/vmware/doc-fr/_build/html/_static/down.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/down.png rename to connectors/vmware/doc-fr/_build/html/_static/down.png diff --git a/connectors/vmware/doc/_build/html/_static/file.png b/connectors/vmware/doc-fr/_build/html/_static/file.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/file.png rename to connectors/vmware/doc-fr/_build/html/_static/file.png diff --git a/connectors/vmware/doc/_build/html/_static/jquery.js b/connectors/vmware/doc-fr/_build/html/_static/jquery.js similarity index 100% rename from connectors/vmware/doc/_build/html/_static/jquery.js rename to connectors/vmware/doc-fr/_build/html/_static/jquery.js diff --git a/connectors/vmware/doc/_build/html/_static/minus.png b/connectors/vmware/doc-fr/_build/html/_static/minus.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/minus.png rename to connectors/vmware/doc-fr/_build/html/_static/minus.png diff --git a/connectors/vmware/doc/_build/html/_static/plus.png b/connectors/vmware/doc-fr/_build/html/_static/plus.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/plus.png rename to connectors/vmware/doc-fr/_build/html/_static/plus.png diff --git a/connectors/vmware/doc/_build/html/_static/pygments.css b/connectors/vmware/doc-fr/_build/html/_static/pygments.css similarity index 100% rename from connectors/vmware/doc/_build/html/_static/pygments.css rename to connectors/vmware/doc-fr/_build/html/_static/pygments.css diff --git a/connectors/vmware/doc/_build/html/_static/searchtools.js b/connectors/vmware/doc-fr/_build/html/_static/searchtools.js similarity index 100% rename from connectors/vmware/doc/_build/html/_static/searchtools.js rename to connectors/vmware/doc-fr/_build/html/_static/searchtools.js diff --git a/connectors/vmware/doc/_build/html/_static/sidebar.js b/connectors/vmware/doc-fr/_build/html/_static/sidebar.js similarity index 100% rename from connectors/vmware/doc/_build/html/_static/sidebar.js rename to connectors/vmware/doc-fr/_build/html/_static/sidebar.js diff --git a/connectors/vmware/doc/_build/html/_static/underscore.js b/connectors/vmware/doc-fr/_build/html/_static/underscore.js similarity index 100% rename from connectors/vmware/doc/_build/html/_static/underscore.js rename to connectors/vmware/doc-fr/_build/html/_static/underscore.js diff --git a/connectors/vmware/doc/_build/html/_static/up-pressed.png b/connectors/vmware/doc-fr/_build/html/_static/up-pressed.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/up-pressed.png rename to connectors/vmware/doc-fr/_build/html/_static/up-pressed.png diff --git a/connectors/vmware/doc/_build/html/_static/up.png b/connectors/vmware/doc-fr/_build/html/_static/up.png similarity index 100% rename from connectors/vmware/doc/_build/html/_static/up.png rename to connectors/vmware/doc-fr/_build/html/_static/up.png diff --git a/connectors/vmware/doc/_build/html/_static/websupport.js b/connectors/vmware/doc-fr/_build/html/_static/websupport.js similarity index 100% rename from connectors/vmware/doc/_build/html/_static/websupport.js rename to connectors/vmware/doc-fr/_build/html/_static/websupport.js diff --git a/connectors/vmware/doc/_build/html/exploitation/index.html b/connectors/vmware/doc-fr/_build/html/exploitation/index.html similarity index 100% rename from connectors/vmware/doc/_build/html/exploitation/index.html rename to connectors/vmware/doc-fr/_build/html/exploitation/index.html diff --git a/connectors/vmware/doc/_build/html/genindex.html b/connectors/vmware/doc-fr/_build/html/genindex.html similarity index 100% rename from connectors/vmware/doc/_build/html/genindex.html rename to connectors/vmware/doc-fr/_build/html/genindex.html diff --git a/connectors/vmware/doc/_build/html/index.html b/connectors/vmware/doc-fr/_build/html/index.html similarity index 100% rename from connectors/vmware/doc/_build/html/index.html rename to connectors/vmware/doc-fr/_build/html/index.html diff --git a/connectors/vmware/doc/_build/html/installation/index.html b/connectors/vmware/doc-fr/_build/html/installation/index.html similarity index 100% rename from connectors/vmware/doc/_build/html/installation/index.html rename to connectors/vmware/doc-fr/_build/html/installation/index.html diff --git a/connectors/vmware/doc/_build/html/objects.inv b/connectors/vmware/doc-fr/_build/html/objects.inv similarity index 100% rename from connectors/vmware/doc/_build/html/objects.inv rename to connectors/vmware/doc-fr/_build/html/objects.inv diff --git a/connectors/vmware/doc/_build/html/search.html b/connectors/vmware/doc-fr/_build/html/search.html similarity index 100% rename from connectors/vmware/doc/_build/html/search.html rename to connectors/vmware/doc-fr/_build/html/search.html diff --git a/connectors/vmware/doc/_build/html/searchindex.js b/connectors/vmware/doc-fr/_build/html/searchindex.js similarity index 100% rename from connectors/vmware/doc/_build/html/searchindex.js rename to connectors/vmware/doc-fr/_build/html/searchindex.js diff --git a/connectors/vmware/doc/conf.py b/connectors/vmware/doc-fr/conf.py similarity index 100% rename from connectors/vmware/doc/conf.py rename to connectors/vmware/doc-fr/conf.py diff --git a/connectors/vmware/doc/exploitation/index.rst b/connectors/vmware/doc-fr/exploitation/index.rst similarity index 100% rename from connectors/vmware/doc/exploitation/index.rst rename to connectors/vmware/doc-fr/exploitation/index.rst diff --git a/connectors/vmware/doc/images/archi.png b/connectors/vmware/doc-fr/images/archi.png similarity index 100% rename from connectors/vmware/doc/images/archi.png rename to connectors/vmware/doc-fr/images/archi.png diff --git a/connectors/vmware/doc/index.rst b/connectors/vmware/doc-fr/index.rst similarity index 100% rename from connectors/vmware/doc/index.rst rename to connectors/vmware/doc-fr/index.rst diff --git a/connectors/vmware/doc/installation/index.rst b/connectors/vmware/doc-fr/installation/index.rst similarity index 100% rename from connectors/vmware/doc/installation/index.rst rename to connectors/vmware/doc-fr/installation/index.rst From b773c4e480d36d972d8b258aa17c4c648b76d13b Mon Sep 17 00:00:00 2001 From: qdelance Date: Wed, 7 May 2014 09:39:55 +0200 Subject: [PATCH 080/447] Doc tree reorg to comply with internal conventions --- connectors/vmware/{doc-en => doc/en}/Makefile | 0 .../en}/_build/doctrees/environment.pickle | Bin .../en}/_build/doctrees/exploitation/index.doctree | Bin .../en}/_build/doctrees/index.doctree | Bin .../en}/_build/doctrees/installation/index.doctree | Bin .../{doc-en => doc/en}/_build/html/.buildinfo | 0 .../en}/_build/html/_images/archi.png | Bin .../en}/_build/html/_sources/exploitation/index.txt | 0 .../en}/_build/html/_sources/index.txt | 0 .../en}/_build/html/_sources/installation/index.txt | 0 .../en}/_build/html/_static/ajax-loader.gif | Bin .../en}/_build/html/_static/basic.css | 0 .../en}/_build/html/_static/comment-bright.png | Bin .../en}/_build/html/_static/comment-close.png | Bin .../en}/_build/html/_static/comment.png | Bin .../en}/_build/html/_static/default.css | 0 .../en}/_build/html/_static/doctools.js | 0 .../en}/_build/html/_static/down-pressed.png | Bin .../{doc-en => doc/en}/_build/html/_static/down.png | Bin .../{doc-en => doc/en}/_build/html/_static/file.png | Bin .../en}/_build/html/_static/jquery.js | 0 .../en}/_build/html/_static/minus.png | Bin .../{doc-en => doc/en}/_build/html/_static/plus.png | Bin .../en}/_build/html/_static/pygments.css | 0 .../en}/_build/html/_static/searchtools.js | 0 .../en}/_build/html/_static/sidebar.js | 0 .../en}/_build/html/_static/underscore.js | 0 .../en}/_build/html/_static/up-pressed.png | Bin .../{doc-en => doc/en}/_build/html/_static/up.png | Bin .../en}/_build/html/_static/websupport.js | 0 .../en}/_build/html/exploitation/index.html | 0 .../{doc-en => doc/en}/_build/html/genindex.html | 0 .../{doc-en => doc/en}/_build/html/index.html | 0 .../en}/_build/html/installation/index.html | 0 .../{doc-en => doc/en}/_build/html/objects.inv | Bin .../{doc-en => doc/en}/_build/html/search.html | 0 .../{doc-en => doc/en}/_build/html/searchindex.js | 0 connectors/vmware/{doc-en => doc/en}/conf.py | 0 .../{doc-en => doc/en}/exploitation/index.rst | 0 .../vmware/{doc-en => doc/en}/images/archi.png | Bin connectors/vmware/{doc-en => doc/en}/index.rst | 0 .../{doc-en => doc/en}/installation/index.rst | 0 connectors/vmware/{doc-fr => doc/fr}/Makefile | 0 .../fr}/_build/doctrees/environment.pickle | Bin .../fr}/_build/doctrees/exploitation/index.doctree | Bin .../fr}/_build/doctrees/index.doctree | Bin .../fr}/_build/doctrees/installation/index.doctree | Bin .../{doc-fr => doc/fr}/_build/html/.buildinfo | 0 .../fr}/_build/html/_images/archi.png | Bin .../fr}/_build/html/_sources/exploitation/index.txt | 0 .../fr}/_build/html/_sources/index.txt | 0 .../fr}/_build/html/_sources/installation/index.txt | 0 .../fr}/_build/html/_static/ajax-loader.gif | Bin .../fr}/_build/html/_static/basic.css | 0 .../fr}/_build/html/_static/comment-bright.png | Bin .../fr}/_build/html/_static/comment-close.png | Bin .../fr}/_build/html/_static/comment.png | Bin .../fr}/_build/html/_static/default.css | 0 .../fr}/_build/html/_static/doctools.js | 0 .../fr}/_build/html/_static/down-pressed.png | Bin .../{doc-fr => doc/fr}/_build/html/_static/down.png | Bin .../{doc-fr => doc/fr}/_build/html/_static/file.png | Bin .../fr}/_build/html/_static/jquery.js | 0 .../fr}/_build/html/_static/minus.png | Bin .../{doc-fr => doc/fr}/_build/html/_static/plus.png | Bin .../fr}/_build/html/_static/pygments.css | 0 .../fr}/_build/html/_static/searchtools.js | 0 .../fr}/_build/html/_static/sidebar.js | 0 .../fr}/_build/html/_static/underscore.js | 0 .../fr}/_build/html/_static/up-pressed.png | Bin .../{doc-fr => doc/fr}/_build/html/_static/up.png | Bin .../fr}/_build/html/_static/websupport.js | 0 .../fr}/_build/html/exploitation/index.html | 0 .../{doc-fr => doc/fr}/_build/html/genindex.html | 0 .../{doc-fr => doc/fr}/_build/html/index.html | 0 .../fr}/_build/html/installation/index.html | 0 .../{doc-fr => doc/fr}/_build/html/objects.inv | Bin .../{doc-fr => doc/fr}/_build/html/search.html | 0 .../{doc-fr => doc/fr}/_build/html/searchindex.js | 0 connectors/vmware/{doc-fr => doc/fr}/conf.py | 0 .../{doc-fr => doc/fr}/exploitation/index.rst | 0 .../vmware/{doc-fr => doc/fr}/images/archi.png | Bin connectors/vmware/{doc-fr => doc/fr}/index.rst | 0 .../{doc-fr => doc/fr}/installation/index.rst | 0 84 files changed, 0 insertions(+), 0 deletions(-) rename connectors/vmware/{doc-en => doc/en}/Makefile (100%) rename connectors/vmware/{doc-en => doc/en}/_build/doctrees/environment.pickle (100%) rename connectors/vmware/{doc-en => doc/en}/_build/doctrees/exploitation/index.doctree (100%) rename connectors/vmware/{doc-en => doc/en}/_build/doctrees/index.doctree (100%) rename connectors/vmware/{doc-en => doc/en}/_build/doctrees/installation/index.doctree (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/.buildinfo (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_images/archi.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_sources/exploitation/index.txt (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_sources/index.txt (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_sources/installation/index.txt (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/ajax-loader.gif (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/basic.css (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/comment-bright.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/comment-close.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/comment.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/default.css (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/doctools.js (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/down-pressed.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/down.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/file.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/jquery.js (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/minus.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/plus.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/pygments.css (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/searchtools.js (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/sidebar.js (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/underscore.js (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/up-pressed.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/up.png (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/_static/websupport.js (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/exploitation/index.html (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/genindex.html (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/index.html (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/installation/index.html (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/objects.inv (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/search.html (100%) rename connectors/vmware/{doc-en => doc/en}/_build/html/searchindex.js (100%) rename connectors/vmware/{doc-en => doc/en}/conf.py (100%) rename connectors/vmware/{doc-en => doc/en}/exploitation/index.rst (100%) rename connectors/vmware/{doc-en => doc/en}/images/archi.png (100%) rename connectors/vmware/{doc-en => doc/en}/index.rst (100%) rename connectors/vmware/{doc-en => doc/en}/installation/index.rst (100%) rename connectors/vmware/{doc-fr => doc/fr}/Makefile (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/doctrees/environment.pickle (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/doctrees/exploitation/index.doctree (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/doctrees/index.doctree (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/doctrees/installation/index.doctree (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/.buildinfo (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_images/archi.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_sources/exploitation/index.txt (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_sources/index.txt (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_sources/installation/index.txt (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/ajax-loader.gif (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/basic.css (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/comment-bright.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/comment-close.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/comment.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/default.css (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/doctools.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/down-pressed.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/down.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/file.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/jquery.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/minus.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/plus.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/pygments.css (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/searchtools.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/sidebar.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/underscore.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/up-pressed.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/up.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/_static/websupport.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/exploitation/index.html (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/genindex.html (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/index.html (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/installation/index.html (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/objects.inv (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/search.html (100%) rename connectors/vmware/{doc-fr => doc/fr}/_build/html/searchindex.js (100%) rename connectors/vmware/{doc-fr => doc/fr}/conf.py (100%) rename connectors/vmware/{doc-fr => doc/fr}/exploitation/index.rst (100%) rename connectors/vmware/{doc-fr => doc/fr}/images/archi.png (100%) rename connectors/vmware/{doc-fr => doc/fr}/index.rst (100%) rename connectors/vmware/{doc-fr => doc/fr}/installation/index.rst (100%) diff --git a/connectors/vmware/doc-en/Makefile b/connectors/vmware/doc/en/Makefile similarity index 100% rename from connectors/vmware/doc-en/Makefile rename to connectors/vmware/doc/en/Makefile diff --git a/connectors/vmware/doc-en/_build/doctrees/environment.pickle b/connectors/vmware/doc/en/_build/doctrees/environment.pickle similarity index 100% rename from connectors/vmware/doc-en/_build/doctrees/environment.pickle rename to connectors/vmware/doc/en/_build/doctrees/environment.pickle diff --git a/connectors/vmware/doc-en/_build/doctrees/exploitation/index.doctree b/connectors/vmware/doc/en/_build/doctrees/exploitation/index.doctree similarity index 100% rename from connectors/vmware/doc-en/_build/doctrees/exploitation/index.doctree rename to connectors/vmware/doc/en/_build/doctrees/exploitation/index.doctree diff --git a/connectors/vmware/doc-en/_build/doctrees/index.doctree b/connectors/vmware/doc/en/_build/doctrees/index.doctree similarity index 100% rename from connectors/vmware/doc-en/_build/doctrees/index.doctree rename to connectors/vmware/doc/en/_build/doctrees/index.doctree diff --git a/connectors/vmware/doc-en/_build/doctrees/installation/index.doctree b/connectors/vmware/doc/en/_build/doctrees/installation/index.doctree similarity index 100% rename from connectors/vmware/doc-en/_build/doctrees/installation/index.doctree rename to connectors/vmware/doc/en/_build/doctrees/installation/index.doctree diff --git a/connectors/vmware/doc-en/_build/html/.buildinfo b/connectors/vmware/doc/en/_build/html/.buildinfo similarity index 100% rename from connectors/vmware/doc-en/_build/html/.buildinfo rename to connectors/vmware/doc/en/_build/html/.buildinfo diff --git a/connectors/vmware/doc-en/_build/html/_images/archi.png b/connectors/vmware/doc/en/_build/html/_images/archi.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_images/archi.png rename to connectors/vmware/doc/en/_build/html/_images/archi.png diff --git a/connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc/en/_build/html/_sources/exploitation/index.txt similarity index 100% rename from connectors/vmware/doc-en/_build/html/_sources/exploitation/index.txt rename to connectors/vmware/doc/en/_build/html/_sources/exploitation/index.txt diff --git a/connectors/vmware/doc-en/_build/html/_sources/index.txt b/connectors/vmware/doc/en/_build/html/_sources/index.txt similarity index 100% rename from connectors/vmware/doc-en/_build/html/_sources/index.txt rename to connectors/vmware/doc/en/_build/html/_sources/index.txt diff --git a/connectors/vmware/doc-en/_build/html/_sources/installation/index.txt b/connectors/vmware/doc/en/_build/html/_sources/installation/index.txt similarity index 100% rename from connectors/vmware/doc-en/_build/html/_sources/installation/index.txt rename to connectors/vmware/doc/en/_build/html/_sources/installation/index.txt diff --git a/connectors/vmware/doc-en/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc/en/_build/html/_static/ajax-loader.gif similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/ajax-loader.gif rename to connectors/vmware/doc/en/_build/html/_static/ajax-loader.gif diff --git a/connectors/vmware/doc-en/_build/html/_static/basic.css b/connectors/vmware/doc/en/_build/html/_static/basic.css similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/basic.css rename to connectors/vmware/doc/en/_build/html/_static/basic.css diff --git a/connectors/vmware/doc-en/_build/html/_static/comment-bright.png b/connectors/vmware/doc/en/_build/html/_static/comment-bright.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/comment-bright.png rename to connectors/vmware/doc/en/_build/html/_static/comment-bright.png diff --git a/connectors/vmware/doc-en/_build/html/_static/comment-close.png b/connectors/vmware/doc/en/_build/html/_static/comment-close.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/comment-close.png rename to connectors/vmware/doc/en/_build/html/_static/comment-close.png diff --git a/connectors/vmware/doc-en/_build/html/_static/comment.png b/connectors/vmware/doc/en/_build/html/_static/comment.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/comment.png rename to connectors/vmware/doc/en/_build/html/_static/comment.png diff --git a/connectors/vmware/doc-en/_build/html/_static/default.css b/connectors/vmware/doc/en/_build/html/_static/default.css similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/default.css rename to connectors/vmware/doc/en/_build/html/_static/default.css diff --git a/connectors/vmware/doc-en/_build/html/_static/doctools.js b/connectors/vmware/doc/en/_build/html/_static/doctools.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/doctools.js rename to connectors/vmware/doc/en/_build/html/_static/doctools.js diff --git a/connectors/vmware/doc-en/_build/html/_static/down-pressed.png b/connectors/vmware/doc/en/_build/html/_static/down-pressed.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/down-pressed.png rename to connectors/vmware/doc/en/_build/html/_static/down-pressed.png diff --git a/connectors/vmware/doc-en/_build/html/_static/down.png b/connectors/vmware/doc/en/_build/html/_static/down.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/down.png rename to connectors/vmware/doc/en/_build/html/_static/down.png diff --git a/connectors/vmware/doc-en/_build/html/_static/file.png b/connectors/vmware/doc/en/_build/html/_static/file.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/file.png rename to connectors/vmware/doc/en/_build/html/_static/file.png diff --git a/connectors/vmware/doc-en/_build/html/_static/jquery.js b/connectors/vmware/doc/en/_build/html/_static/jquery.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/jquery.js rename to connectors/vmware/doc/en/_build/html/_static/jquery.js diff --git a/connectors/vmware/doc-en/_build/html/_static/minus.png b/connectors/vmware/doc/en/_build/html/_static/minus.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/minus.png rename to connectors/vmware/doc/en/_build/html/_static/minus.png diff --git a/connectors/vmware/doc-en/_build/html/_static/plus.png b/connectors/vmware/doc/en/_build/html/_static/plus.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/plus.png rename to connectors/vmware/doc/en/_build/html/_static/plus.png diff --git a/connectors/vmware/doc-en/_build/html/_static/pygments.css b/connectors/vmware/doc/en/_build/html/_static/pygments.css similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/pygments.css rename to connectors/vmware/doc/en/_build/html/_static/pygments.css diff --git a/connectors/vmware/doc-en/_build/html/_static/searchtools.js b/connectors/vmware/doc/en/_build/html/_static/searchtools.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/searchtools.js rename to connectors/vmware/doc/en/_build/html/_static/searchtools.js diff --git a/connectors/vmware/doc-en/_build/html/_static/sidebar.js b/connectors/vmware/doc/en/_build/html/_static/sidebar.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/sidebar.js rename to connectors/vmware/doc/en/_build/html/_static/sidebar.js diff --git a/connectors/vmware/doc-en/_build/html/_static/underscore.js b/connectors/vmware/doc/en/_build/html/_static/underscore.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/underscore.js rename to connectors/vmware/doc/en/_build/html/_static/underscore.js diff --git a/connectors/vmware/doc-en/_build/html/_static/up-pressed.png b/connectors/vmware/doc/en/_build/html/_static/up-pressed.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/up-pressed.png rename to connectors/vmware/doc/en/_build/html/_static/up-pressed.png diff --git a/connectors/vmware/doc-en/_build/html/_static/up.png b/connectors/vmware/doc/en/_build/html/_static/up.png similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/up.png rename to connectors/vmware/doc/en/_build/html/_static/up.png diff --git a/connectors/vmware/doc-en/_build/html/_static/websupport.js b/connectors/vmware/doc/en/_build/html/_static/websupport.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/_static/websupport.js rename to connectors/vmware/doc/en/_build/html/_static/websupport.js diff --git a/connectors/vmware/doc-en/_build/html/exploitation/index.html b/connectors/vmware/doc/en/_build/html/exploitation/index.html similarity index 100% rename from connectors/vmware/doc-en/_build/html/exploitation/index.html rename to connectors/vmware/doc/en/_build/html/exploitation/index.html diff --git a/connectors/vmware/doc-en/_build/html/genindex.html b/connectors/vmware/doc/en/_build/html/genindex.html similarity index 100% rename from connectors/vmware/doc-en/_build/html/genindex.html rename to connectors/vmware/doc/en/_build/html/genindex.html diff --git a/connectors/vmware/doc-en/_build/html/index.html b/connectors/vmware/doc/en/_build/html/index.html similarity index 100% rename from connectors/vmware/doc-en/_build/html/index.html rename to connectors/vmware/doc/en/_build/html/index.html diff --git a/connectors/vmware/doc-en/_build/html/installation/index.html b/connectors/vmware/doc/en/_build/html/installation/index.html similarity index 100% rename from connectors/vmware/doc-en/_build/html/installation/index.html rename to connectors/vmware/doc/en/_build/html/installation/index.html diff --git a/connectors/vmware/doc-en/_build/html/objects.inv b/connectors/vmware/doc/en/_build/html/objects.inv similarity index 100% rename from connectors/vmware/doc-en/_build/html/objects.inv rename to connectors/vmware/doc/en/_build/html/objects.inv diff --git a/connectors/vmware/doc-en/_build/html/search.html b/connectors/vmware/doc/en/_build/html/search.html similarity index 100% rename from connectors/vmware/doc-en/_build/html/search.html rename to connectors/vmware/doc/en/_build/html/search.html diff --git a/connectors/vmware/doc-en/_build/html/searchindex.js b/connectors/vmware/doc/en/_build/html/searchindex.js similarity index 100% rename from connectors/vmware/doc-en/_build/html/searchindex.js rename to connectors/vmware/doc/en/_build/html/searchindex.js diff --git a/connectors/vmware/doc-en/conf.py b/connectors/vmware/doc/en/conf.py similarity index 100% rename from connectors/vmware/doc-en/conf.py rename to connectors/vmware/doc/en/conf.py diff --git a/connectors/vmware/doc-en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst similarity index 100% rename from connectors/vmware/doc-en/exploitation/index.rst rename to connectors/vmware/doc/en/exploitation/index.rst diff --git a/connectors/vmware/doc-en/images/archi.png b/connectors/vmware/doc/en/images/archi.png similarity index 100% rename from connectors/vmware/doc-en/images/archi.png rename to connectors/vmware/doc/en/images/archi.png diff --git a/connectors/vmware/doc-en/index.rst b/connectors/vmware/doc/en/index.rst similarity index 100% rename from connectors/vmware/doc-en/index.rst rename to connectors/vmware/doc/en/index.rst diff --git a/connectors/vmware/doc-en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst similarity index 100% rename from connectors/vmware/doc-en/installation/index.rst rename to connectors/vmware/doc/en/installation/index.rst diff --git a/connectors/vmware/doc-fr/Makefile b/connectors/vmware/doc/fr/Makefile similarity index 100% rename from connectors/vmware/doc-fr/Makefile rename to connectors/vmware/doc/fr/Makefile diff --git a/connectors/vmware/doc-fr/_build/doctrees/environment.pickle b/connectors/vmware/doc/fr/_build/doctrees/environment.pickle similarity index 100% rename from connectors/vmware/doc-fr/_build/doctrees/environment.pickle rename to connectors/vmware/doc/fr/_build/doctrees/environment.pickle diff --git a/connectors/vmware/doc-fr/_build/doctrees/exploitation/index.doctree b/connectors/vmware/doc/fr/_build/doctrees/exploitation/index.doctree similarity index 100% rename from connectors/vmware/doc-fr/_build/doctrees/exploitation/index.doctree rename to connectors/vmware/doc/fr/_build/doctrees/exploitation/index.doctree diff --git a/connectors/vmware/doc-fr/_build/doctrees/index.doctree b/connectors/vmware/doc/fr/_build/doctrees/index.doctree similarity index 100% rename from connectors/vmware/doc-fr/_build/doctrees/index.doctree rename to connectors/vmware/doc/fr/_build/doctrees/index.doctree diff --git a/connectors/vmware/doc-fr/_build/doctrees/installation/index.doctree b/connectors/vmware/doc/fr/_build/doctrees/installation/index.doctree similarity index 100% rename from connectors/vmware/doc-fr/_build/doctrees/installation/index.doctree rename to connectors/vmware/doc/fr/_build/doctrees/installation/index.doctree diff --git a/connectors/vmware/doc-fr/_build/html/.buildinfo b/connectors/vmware/doc/fr/_build/html/.buildinfo similarity index 100% rename from connectors/vmware/doc-fr/_build/html/.buildinfo rename to connectors/vmware/doc/fr/_build/html/.buildinfo diff --git a/connectors/vmware/doc-fr/_build/html/_images/archi.png b/connectors/vmware/doc/fr/_build/html/_images/archi.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_images/archi.png rename to connectors/vmware/doc/fr/_build/html/_images/archi.png diff --git a/connectors/vmware/doc-fr/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc/fr/_build/html/_sources/exploitation/index.txt similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_sources/exploitation/index.txt rename to connectors/vmware/doc/fr/_build/html/_sources/exploitation/index.txt diff --git a/connectors/vmware/doc-fr/_build/html/_sources/index.txt b/connectors/vmware/doc/fr/_build/html/_sources/index.txt similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_sources/index.txt rename to connectors/vmware/doc/fr/_build/html/_sources/index.txt diff --git a/connectors/vmware/doc-fr/_build/html/_sources/installation/index.txt b/connectors/vmware/doc/fr/_build/html/_sources/installation/index.txt similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_sources/installation/index.txt rename to connectors/vmware/doc/fr/_build/html/_sources/installation/index.txt diff --git a/connectors/vmware/doc-fr/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc/fr/_build/html/_static/ajax-loader.gif similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/ajax-loader.gif rename to connectors/vmware/doc/fr/_build/html/_static/ajax-loader.gif diff --git a/connectors/vmware/doc-fr/_build/html/_static/basic.css b/connectors/vmware/doc/fr/_build/html/_static/basic.css similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/basic.css rename to connectors/vmware/doc/fr/_build/html/_static/basic.css diff --git a/connectors/vmware/doc-fr/_build/html/_static/comment-bright.png b/connectors/vmware/doc/fr/_build/html/_static/comment-bright.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/comment-bright.png rename to connectors/vmware/doc/fr/_build/html/_static/comment-bright.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/comment-close.png b/connectors/vmware/doc/fr/_build/html/_static/comment-close.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/comment-close.png rename to connectors/vmware/doc/fr/_build/html/_static/comment-close.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/comment.png b/connectors/vmware/doc/fr/_build/html/_static/comment.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/comment.png rename to connectors/vmware/doc/fr/_build/html/_static/comment.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/default.css b/connectors/vmware/doc/fr/_build/html/_static/default.css similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/default.css rename to connectors/vmware/doc/fr/_build/html/_static/default.css diff --git a/connectors/vmware/doc-fr/_build/html/_static/doctools.js b/connectors/vmware/doc/fr/_build/html/_static/doctools.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/doctools.js rename to connectors/vmware/doc/fr/_build/html/_static/doctools.js diff --git a/connectors/vmware/doc-fr/_build/html/_static/down-pressed.png b/connectors/vmware/doc/fr/_build/html/_static/down-pressed.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/down-pressed.png rename to connectors/vmware/doc/fr/_build/html/_static/down-pressed.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/down.png b/connectors/vmware/doc/fr/_build/html/_static/down.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/down.png rename to connectors/vmware/doc/fr/_build/html/_static/down.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/file.png b/connectors/vmware/doc/fr/_build/html/_static/file.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/file.png rename to connectors/vmware/doc/fr/_build/html/_static/file.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/jquery.js b/connectors/vmware/doc/fr/_build/html/_static/jquery.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/jquery.js rename to connectors/vmware/doc/fr/_build/html/_static/jquery.js diff --git a/connectors/vmware/doc-fr/_build/html/_static/minus.png b/connectors/vmware/doc/fr/_build/html/_static/minus.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/minus.png rename to connectors/vmware/doc/fr/_build/html/_static/minus.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/plus.png b/connectors/vmware/doc/fr/_build/html/_static/plus.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/plus.png rename to connectors/vmware/doc/fr/_build/html/_static/plus.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/pygments.css b/connectors/vmware/doc/fr/_build/html/_static/pygments.css similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/pygments.css rename to connectors/vmware/doc/fr/_build/html/_static/pygments.css diff --git a/connectors/vmware/doc-fr/_build/html/_static/searchtools.js b/connectors/vmware/doc/fr/_build/html/_static/searchtools.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/searchtools.js rename to connectors/vmware/doc/fr/_build/html/_static/searchtools.js diff --git a/connectors/vmware/doc-fr/_build/html/_static/sidebar.js b/connectors/vmware/doc/fr/_build/html/_static/sidebar.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/sidebar.js rename to connectors/vmware/doc/fr/_build/html/_static/sidebar.js diff --git a/connectors/vmware/doc-fr/_build/html/_static/underscore.js b/connectors/vmware/doc/fr/_build/html/_static/underscore.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/underscore.js rename to connectors/vmware/doc/fr/_build/html/_static/underscore.js diff --git a/connectors/vmware/doc-fr/_build/html/_static/up-pressed.png b/connectors/vmware/doc/fr/_build/html/_static/up-pressed.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/up-pressed.png rename to connectors/vmware/doc/fr/_build/html/_static/up-pressed.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/up.png b/connectors/vmware/doc/fr/_build/html/_static/up.png similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/up.png rename to connectors/vmware/doc/fr/_build/html/_static/up.png diff --git a/connectors/vmware/doc-fr/_build/html/_static/websupport.js b/connectors/vmware/doc/fr/_build/html/_static/websupport.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/_static/websupport.js rename to connectors/vmware/doc/fr/_build/html/_static/websupport.js diff --git a/connectors/vmware/doc-fr/_build/html/exploitation/index.html b/connectors/vmware/doc/fr/_build/html/exploitation/index.html similarity index 100% rename from connectors/vmware/doc-fr/_build/html/exploitation/index.html rename to connectors/vmware/doc/fr/_build/html/exploitation/index.html diff --git a/connectors/vmware/doc-fr/_build/html/genindex.html b/connectors/vmware/doc/fr/_build/html/genindex.html similarity index 100% rename from connectors/vmware/doc-fr/_build/html/genindex.html rename to connectors/vmware/doc/fr/_build/html/genindex.html diff --git a/connectors/vmware/doc-fr/_build/html/index.html b/connectors/vmware/doc/fr/_build/html/index.html similarity index 100% rename from connectors/vmware/doc-fr/_build/html/index.html rename to connectors/vmware/doc/fr/_build/html/index.html diff --git a/connectors/vmware/doc-fr/_build/html/installation/index.html b/connectors/vmware/doc/fr/_build/html/installation/index.html similarity index 100% rename from connectors/vmware/doc-fr/_build/html/installation/index.html rename to connectors/vmware/doc/fr/_build/html/installation/index.html diff --git a/connectors/vmware/doc-fr/_build/html/objects.inv b/connectors/vmware/doc/fr/_build/html/objects.inv similarity index 100% rename from connectors/vmware/doc-fr/_build/html/objects.inv rename to connectors/vmware/doc/fr/_build/html/objects.inv diff --git a/connectors/vmware/doc-fr/_build/html/search.html b/connectors/vmware/doc/fr/_build/html/search.html similarity index 100% rename from connectors/vmware/doc-fr/_build/html/search.html rename to connectors/vmware/doc/fr/_build/html/search.html diff --git a/connectors/vmware/doc-fr/_build/html/searchindex.js b/connectors/vmware/doc/fr/_build/html/searchindex.js similarity index 100% rename from connectors/vmware/doc-fr/_build/html/searchindex.js rename to connectors/vmware/doc/fr/_build/html/searchindex.js diff --git a/connectors/vmware/doc-fr/conf.py b/connectors/vmware/doc/fr/conf.py similarity index 100% rename from connectors/vmware/doc-fr/conf.py rename to connectors/vmware/doc/fr/conf.py diff --git a/connectors/vmware/doc-fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst similarity index 100% rename from connectors/vmware/doc-fr/exploitation/index.rst rename to connectors/vmware/doc/fr/exploitation/index.rst diff --git a/connectors/vmware/doc-fr/images/archi.png b/connectors/vmware/doc/fr/images/archi.png similarity index 100% rename from connectors/vmware/doc-fr/images/archi.png rename to connectors/vmware/doc/fr/images/archi.png diff --git a/connectors/vmware/doc-fr/index.rst b/connectors/vmware/doc/fr/index.rst similarity index 100% rename from connectors/vmware/doc-fr/index.rst rename to connectors/vmware/doc/fr/index.rst diff --git a/connectors/vmware/doc-fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst similarity index 100% rename from connectors/vmware/doc-fr/installation/index.rst rename to connectors/vmware/doc/fr/installation/index.rst From 0abe026da1ac51c78bf3bbd2e046b922179bdf62 Mon Sep 17 00:00:00 2001 From: qdelance Date: Wed, 7 May 2014 09:42:56 +0200 Subject: [PATCH 081/447] Remove generated HTML docs --- .../doc/en/_build/doctrees/environment.pickle | Bin 55525 -> 0 bytes .../doctrees/exploitation/index.doctree | Bin 410975 -> 0 bytes .../doc/en/_build/doctrees/index.doctree | Bin 6186 -> 0 bytes .../doctrees/installation/index.doctree | Bin 31184 -> 0 bytes .../vmware/doc/en/_build/html/.buildinfo | 4 - .../doc/en/_build/html/_images/archi.png | Bin 25993 -> 0 bytes .../html/_sources/exploitation/index.txt | 1384 ---------- .../doc/en/_build/html/_sources/index.txt | 24 - .../html/_sources/installation/index.txt | 184 -- .../en/_build/html/_static/ajax-loader.gif | Bin 673 -> 0 bytes .../doc/en/_build/html/_static/basic.css | 540 ---- .../en/_build/html/_static/comment-bright.png | Bin 3500 -> 0 bytes .../en/_build/html/_static/comment-close.png | Bin 3578 -> 0 bytes .../doc/en/_build/html/_static/comment.png | Bin 3445 -> 0 bytes .../doc/en/_build/html/_static/default.css | 256 -- .../doc/en/_build/html/_static/doctools.js | 247 -- .../en/_build/html/_static/down-pressed.png | Bin 368 -> 0 bytes .../doc/en/_build/html/_static/down.png | Bin 363 -> 0 bytes .../doc/en/_build/html/_static/file.png | Bin 392 -> 0 bytes .../doc/en/_build/html/_static/jquery.js | 154 -- .../doc/en/_build/html/_static/minus.png | Bin 199 -> 0 bytes .../doc/en/_build/html/_static/plus.png | Bin 199 -> 0 bytes .../doc/en/_build/html/_static/pygments.css | 62 - .../doc/en/_build/html/_static/searchtools.js | 560 ---- .../doc/en/_build/html/_static/sidebar.js | 151 -- .../doc/en/_build/html/_static/underscore.js | 23 - .../doc/en/_build/html/_static/up-pressed.png | Bin 372 -> 0 bytes .../vmware/doc/en/_build/html/_static/up.png | Bin 363 -> 0 bytes .../doc/en/_build/html/_static/websupport.js | 808 ------ .../en/_build/html/exploitation/index.html | 2378 ----------------- .../vmware/doc/en/_build/html/genindex.html | 95 - .../vmware/doc/en/_build/html/index.html | 135 - .../en/_build/html/installation/index.html | 313 --- .../vmware/doc/en/_build/html/objects.inv | Bin 209 -> 0 bytes .../vmware/doc/en/_build/html/search.html | 99 - .../vmware/doc/en/_build/html/searchindex.js | 1 - .../doc/fr/_build/doctrees/environment.pickle | Bin 43441 -> 0 bytes .../doctrees/exploitation/index.doctree | Bin 341484 -> 0 bytes .../doc/fr/_build/doctrees/index.doctree | Bin 5558 -> 0 bytes .../doctrees/installation/index.doctree | Bin 31121 -> 0 bytes .../vmware/doc/fr/_build/html/.buildinfo | 4 - .../doc/fr/_build/html/_images/archi.png | Bin 29775 -> 0 bytes .../html/_sources/exploitation/index.txt | 1384 ---------- .../doc/fr/_build/html/_sources/index.txt | 24 - .../html/_sources/installation/index.txt | 191 -- .../fr/_build/html/_static/ajax-loader.gif | Bin 673 -> 0 bytes .../doc/fr/_build/html/_static/basic.css | 540 ---- .../fr/_build/html/_static/comment-bright.png | Bin 3500 -> 0 bytes .../fr/_build/html/_static/comment-close.png | Bin 3578 -> 0 bytes .../doc/fr/_build/html/_static/comment.png | Bin 3445 -> 0 bytes .../doc/fr/_build/html/_static/default.css | 256 -- .../doc/fr/_build/html/_static/doctools.js | 235 -- .../fr/_build/html/_static/down-pressed.png | Bin 368 -> 0 bytes .../doc/fr/_build/html/_static/down.png | Bin 363 -> 0 bytes .../doc/fr/_build/html/_static/file.png | Bin 392 -> 0 bytes .../doc/fr/_build/html/_static/jquery.js | 4 - .../doc/fr/_build/html/_static/minus.png | Bin 199 -> 0 bytes .../doc/fr/_build/html/_static/plus.png | Bin 199 -> 0 bytes .../doc/fr/_build/html/_static/pygments.css | 62 - .../doc/fr/_build/html/_static/searchtools.js | 622 ----- .../doc/fr/_build/html/_static/sidebar.js | 159 -- .../doc/fr/_build/html/_static/underscore.js | 31 - .../doc/fr/_build/html/_static/up-pressed.png | Bin 372 -> 0 bytes .../vmware/doc/fr/_build/html/_static/up.png | Bin 363 -> 0 bytes .../doc/fr/_build/html/_static/websupport.js | 808 ------ .../fr/_build/html/exploitation/index.html | 2376 ---------------- .../vmware/doc/fr/_build/html/genindex.html | 92 - .../vmware/doc/fr/_build/html/index.html | 133 - .../fr/_build/html/installation/index.html | 314 --- .../vmware/doc/fr/_build/html/objects.inv | Bin 209 -> 0 bytes .../vmware/doc/fr/_build/html/search.html | 99 - .../vmware/doc/fr/_build/html/searchindex.js | 1 - 72 files changed, 14753 deletions(-) delete mode 100644 connectors/vmware/doc/en/_build/doctrees/environment.pickle delete mode 100644 connectors/vmware/doc/en/_build/doctrees/exploitation/index.doctree delete mode 100644 connectors/vmware/doc/en/_build/doctrees/index.doctree delete mode 100644 connectors/vmware/doc/en/_build/doctrees/installation/index.doctree delete mode 100644 connectors/vmware/doc/en/_build/html/.buildinfo delete mode 100644 connectors/vmware/doc/en/_build/html/_images/archi.png delete mode 100644 connectors/vmware/doc/en/_build/html/_sources/exploitation/index.txt delete mode 100644 connectors/vmware/doc/en/_build/html/_sources/index.txt delete mode 100644 connectors/vmware/doc/en/_build/html/_sources/installation/index.txt delete mode 100644 connectors/vmware/doc/en/_build/html/_static/ajax-loader.gif delete mode 100644 connectors/vmware/doc/en/_build/html/_static/basic.css delete mode 100644 connectors/vmware/doc/en/_build/html/_static/comment-bright.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/comment-close.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/comment.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/default.css delete mode 100644 connectors/vmware/doc/en/_build/html/_static/doctools.js delete mode 100644 connectors/vmware/doc/en/_build/html/_static/down-pressed.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/down.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/file.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/jquery.js delete mode 100644 connectors/vmware/doc/en/_build/html/_static/minus.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/plus.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/pygments.css delete mode 100644 connectors/vmware/doc/en/_build/html/_static/searchtools.js delete mode 100644 connectors/vmware/doc/en/_build/html/_static/sidebar.js delete mode 100644 connectors/vmware/doc/en/_build/html/_static/underscore.js delete mode 100644 connectors/vmware/doc/en/_build/html/_static/up-pressed.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/up.png delete mode 100644 connectors/vmware/doc/en/_build/html/_static/websupport.js delete mode 100644 connectors/vmware/doc/en/_build/html/exploitation/index.html delete mode 100644 connectors/vmware/doc/en/_build/html/genindex.html delete mode 100644 connectors/vmware/doc/en/_build/html/index.html delete mode 100644 connectors/vmware/doc/en/_build/html/installation/index.html delete mode 100644 connectors/vmware/doc/en/_build/html/objects.inv delete mode 100644 connectors/vmware/doc/en/_build/html/search.html delete mode 100644 connectors/vmware/doc/en/_build/html/searchindex.js delete mode 100644 connectors/vmware/doc/fr/_build/doctrees/environment.pickle delete mode 100644 connectors/vmware/doc/fr/_build/doctrees/exploitation/index.doctree delete mode 100644 connectors/vmware/doc/fr/_build/doctrees/index.doctree delete mode 100644 connectors/vmware/doc/fr/_build/doctrees/installation/index.doctree delete mode 100644 connectors/vmware/doc/fr/_build/html/.buildinfo delete mode 100644 connectors/vmware/doc/fr/_build/html/_images/archi.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_sources/exploitation/index.txt delete mode 100644 connectors/vmware/doc/fr/_build/html/_sources/index.txt delete mode 100644 connectors/vmware/doc/fr/_build/html/_sources/installation/index.txt delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/ajax-loader.gif delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/basic.css delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/comment-bright.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/comment-close.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/comment.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/default.css delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/doctools.js delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/down-pressed.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/down.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/file.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/jquery.js delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/minus.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/plus.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/pygments.css delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/searchtools.js delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/sidebar.js delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/underscore.js delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/up-pressed.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/up.png delete mode 100644 connectors/vmware/doc/fr/_build/html/_static/websupport.js delete mode 100644 connectors/vmware/doc/fr/_build/html/exploitation/index.html delete mode 100644 connectors/vmware/doc/fr/_build/html/genindex.html delete mode 100644 connectors/vmware/doc/fr/_build/html/index.html delete mode 100644 connectors/vmware/doc/fr/_build/html/installation/index.html delete mode 100644 connectors/vmware/doc/fr/_build/html/objects.inv delete mode 100644 connectors/vmware/doc/fr/_build/html/search.html delete mode 100644 connectors/vmware/doc/fr/_build/html/searchindex.js diff --git a/connectors/vmware/doc/en/_build/doctrees/environment.pickle b/connectors/vmware/doc/en/_build/doctrees/environment.pickle deleted file mode 100644 index 72be606ccf1663290f3fef01cd1c363cbf26fa4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55525 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 diff --git a/connectors/vmware/doc/en/_build/doctrees/exploitation/index.doctree b/connectors/vmware/doc/en/_build/doctrees/exploitation/index.doctree deleted file mode 100644 index 04d7eca7394d3723d92f7c302b3774fce8a775f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410975 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

          %#ON{H?F|yTIcZ=ssZNfNxvW2W=TWA%xeGVA3B; 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 Dd|w7? diff --git a/connectors/vmware/doc/en/_build/doctrees/installation/index.doctree b/connectors/vmware/doc/en/_build/doctrees/installation/index.doctree deleted file mode 100644 index d81702bc70cd0960f391941ef22666144ad93d0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31184 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 Oih_))G)&4g=>GsL(zAX5 diff --git a/connectors/vmware/doc/en/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc/en/_build/html/_sources/exploitation/index.txt deleted file mode 100644 index 34cbfba2f..000000000 --- a/connectors/vmware/doc/en/_build/html/_sources/exploitation/index.txt +++ /dev/null @@ -1,1384 +0,0 @@ -============ -Exploitation -============ - -Centreon-esxd Presentation ---------------------------- - -Generals Principles -``````````````````` - -Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter. - -By default "centreon-esxd" starts at least two processes (named "handle-client" and "handle-vsphere-xxxx") : - -*« handle-client »*: - *Process waiting for requests of "centron-esx-client.pl" clients.* - -Steps of operation : - -- A client connects. -- The client ask an monitoring indicator on a VirtualCenter. -- The process "handle-client" sends the request to process "handle-vsphere-xxxx". -- A response is sent by "handle-vsphere-xxxx" to "handle-client". -- The process "handle-client" sends the response to the client. - -*« handle-vsphere-xxxx »*: - *Process responsible to connect and to keep opened a session with the VirtualCenter. To ensure quality performance, a cache of datas description is created.* - -Then, this process gets back the VMWare indicators creating a subprocess per request. - -Centreon-esxd necessitates the utilization of one (or more) VirtualCenter. It isn't possible to get back informations of an ESX server directly. - -This is a example of a fragmented architecture : - -.. image:: ../images/archi.png - -Operating mode -`````````````` -The "centreon-esxd" program only works in "daemon" mode. (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). - -Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. - -Configuration du connecteur -``````````````````````````` -Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - - 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', - 'password' => 'XXXXXX'} - 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"; - -La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. - -La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». - -Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. - -Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. - - -Optimisation de la configuration dans Centreon ----------------------------------------------- - -Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. - -Ce connecteur permet la définition de trois modèles d'hôtes : - -- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. -- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. -- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») - -Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. - -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | -| | | | -+====================+===================================================================+================================================================+ -| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ - -Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». - - -Création d'un modèle d'hôte VMWare générique -```````````````````````````````````````````` - -Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». - -Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. - -Définir les macros suivante : - -+---------------------+-------------------------------------------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+===================================================================+ -| ESXDHOST | Exemple: 10.30.10.30 | -+---------------------+-------------------------------------------------------------------+ -| ESXDPORT | 5700 (port par défaut) | -+---------------------+-------------------------------------------------------------------+ -| VCNAME | default | -+---------------------+-------------------------------------------------------------------+ - -Troubleshooting -``````````````` - -Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: - - ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... - -Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. - -Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. - - -Liste des contrôles -------------------- - -Contrôles ESX -````````````` -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+===========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuhost | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | -| | - le taux d'utilisation mémoire (en octets), | -| | - la taille totale de la mémoire (en octets), | -| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memhost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -RESEAU -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_nethost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux d'utilisation en entrée et sortie (en b/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | nethost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| NICNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -SWAP -'''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_swaphost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | swaphost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 0.8 | -+---------------------+--------------------------------+ -| CRITICAL | 1 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreshost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | -| | - la latence totale en lecture et écriture (en ms). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+============================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoreshost | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 30 | -+---------------------+--------------------------------+ -| CRITICAL | 50 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -COUNTVM -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_countvmhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | -| | - le nombre de machines virtuelles allumées. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | count=45 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | countvmhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 10 | -+---------------------+--------------------------------+ -| CRITICAL | 15 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -HEALTH -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_healthhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | Remonte un état selon l'état des sondes: | -| | - "Yellow" correspond à WARNING. | -| | - "Red" correspond à CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | healthhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MAINTENANCE -''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_maintenancehost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | maintenancehost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -STATUT -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_statushost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état global d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | -| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | -| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | statushost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôles d'une machine virtuelle -````````````````````````````````` - -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuvm | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | -| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | -| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | -| | - « overhead » : la mémoire sur-alloué (en octets) | -| | - « ballooning », « shared » et « active ». | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoresvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | -| | - « riops » : le nombre moyen d'I/O de lectures par seconde | -| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoresvm | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -VMTOOLS -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_toolsvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | -| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | toolsvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -SNAPSHOTS -''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_snapshotvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | L'état dépend des paramètres du plugin : | -| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | -| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | -| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+====================+==========================================================================================+================================================================+ -| -u | Indicateur à contrôler | snapshotvm | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| THRESHOLD | - -warn | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôle d'un datastore -``````````````````````` - -USAGE -''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreusage | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | -| | - « used » : l'espace occupé par le datastore (en octets) | -| | - « size » : la taille totale allouée pour le datastore (en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-usage | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORE I/O -''''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastorio | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | -| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | -| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-io | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - diff --git a/connectors/vmware/doc/en/_build/html/_sources/index.txt b/connectors/vmware/doc/en/_build/html/_sources/index.txt deleted file mode 100644 index 8f840209e..000000000 --- a/connectors/vmware/doc/en/_build/html/_sources/index.txt +++ /dev/null @@ -1,24 +0,0 @@ -.. Centreon ESXD documentation master file, created by - sphinx-quickstart on Mon Apr 22 11:17:38 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Centreon ESXD's documentation! -========================================= - -Contents: - -.. toctree:: - :maxdepth: 2 - - installation/index - exploitation/index - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/connectors/vmware/doc/en/_build/html/_sources/installation/index.txt b/connectors/vmware/doc/en/_build/html/_sources/installation/index.txt deleted file mode 100644 index fd8b2f207..000000000 --- a/connectors/vmware/doc/en/_build/html/_sources/installation/index.txt +++ /dev/null @@ -1,184 +0,0 @@ -============ -Installation -============ - -Prerequisites -============= - -Software Recommandations -```````````````````````` - -The "centreon-esxd" connector has been tested on linux systems. -Installation on other system is possible but is outside the scope of this document. - -==================== ===================== -Software Minimal Version -==================== ===================== -VMWare SDK Perl 5.0 -Perl 5.8 -centreon-esxd 1.3 -==================== ===================== - -Hardware Recommandations -```````````````````````` - -Hardware prerequisites will vary depending on the number of monitored hosts. Without configured, no checks are done. Minimal used ressources are : - -* RAM : 512 Mo (May slightly increase with the number of checks). - -* CPU : same as poller server. - -Centreon-esxd Installation - centos/rhel 5 systems -================================================== - -SDK Perl VMWare Installation -```````````````````````````` - -The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. - - -Install CPAN prerequisites :: - - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay - - root # cpan install Class::MethodMaker - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https - root # cpan install SOAP::Lite - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install - -All SDK prerequisites are installed. - -Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) - -Install VMWare Perl SDK:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install - -Addtionnal Modules Installation -``````````````````````````````` - -Some features require additionnal prerequisites. - -To send data to a syslog daemon, the " Unix::Syslog" must be installed :: - - root # cpan install Unix::Syslog - -To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Reboot your system to complete. - -centreon-esxd Installation -`````````````````````````` - -Download « centreon-esxd » archive, then install :: - - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ - -Configure "centreon-esxd" daemon to start at boot :: - - root # chkconfig --level 2345 centreon_esxd on - - -*"centreon_esx_client.pl" is the corresponding nagios plugin.* - -Centreon-esxd Installation - centos/rhel 6 systems -================================================== - -SDK Perl VMWare Installation -````````````````````````````` - -The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it's the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN. - -Install CPAN prerequisites :: - - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite - - root # cpan install Test::More - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install - -All SDK prerequisites are installed. - -Download the last version on the VMWare website (`SDK VMWare `_) (choose the file correponding to your architecture) - -Install VMWare Perl SDK:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install - -Addtionnal Modules Installation -``````````````````````````````` - -Some features require additionnal prerequisites. - -To send data to a syslog daemon, the " Unix::Syslog" must be installed :: - - root # cpan install Unix::Syslog - -To check a virtual server snapshots date, the "DateTime::Format::ISO8601" is required (**be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous**) :: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Reboot your system to complete. - -centreon-esxd Installation -`````````````````````````` - -Download « centreon-esxd » archive, then install :: - - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ - -Configure "centreon-esxd" daemon to start at boot :: - - root # chkconfig --level 2345 centreon_esxd on - - -*"centreon_esx_client.pl" is the corresponding nagios plugin.* - diff --git a/connectors/vmware/doc/en/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc/en/_build/html/_static/ajax-loader.gif deleted file mode 100644 index 61faf8cab23993bd3e1560bff0668bd628642330..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@Cw{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN diff --git a/connectors/vmware/doc/en/_build/html/_static/basic.css b/connectors/vmware/doc/en/_build/html/_static/basic.css deleted file mode 100644 index 43e8bafaf..000000000 --- a/connectors/vmware/doc/en/_build/html/_static/basic.css +++ /dev/null @@ -1,540 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/_static/comment-bright.png b/connectors/vmware/doc/en/_build/html/_static/comment-bright.png deleted file mode 100644 index 551517b8c83b76f734ff791f847829a760ad1903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3500 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 A2LJ#7 diff --git a/connectors/vmware/doc/en/_build/html/_static/comment.png b/connectors/vmware/doc/en/_build/html/_static/comment.png deleted file mode 100644 index 92feb52b8824c6b0f59b658b1196c61de9162a95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3445 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 Xn!ZpXD%P(H00000NkvXXu0mjf= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('

          ') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); diff --git a/connectors/vmware/doc/en/_build/html/_static/down-pressed.png b/connectors/vmware/doc/en/_build/html/_static/down-pressed.png deleted file mode 100644 index 6f7ad782782e4f8e39b0c6e15c7344700cdd2527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}Z23@f-Ava~9&<9T!#}JFtXD=!G zGdl{fK6ro2OGiOl+hKvH6i=D3%%Y^j`yIkRn!8O>@bG)IQR0{Kf+mxNd=_WScA8u_ z3;8(7x2){m9`nt+U(Nab&1G)!{`SPVpDX$w8McLTzAJ39wprG3p4XLq$06M`%}2Yk zRPPsbES*dnYm1wkGL;iioAUB*Or2kz6(-M_r_#Me-`{mj$Z%( diff --git a/connectors/vmware/doc/en/_build/html/_static/down.png b/connectors/vmware/doc/en/_build/html/_static/down.png deleted file mode 100644 index 3003a88770de3977d47a2ba69893436a2860f9e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}xaV3tUZ$qnrLa#kt978NlpS`ru z&)HFc^}^>{UOEce+71h5nn>6&w6A!ieNbu1wh)UGh{8~et^#oZ1# z>T7oM=FZ~xXWnTo{qnXm$ZLOlqGswI_m2{XwVK)IJmBjW{J3-B3x@C=M{ShWt#fYS9M?R;8K$~YwlIqwf>VA7q=YKcwf2DS4Zj5inDKXXB1zl=(YO3ST6~rDq)&z z*o>z)=hxrfG-cDBW0G$!?6{M<$@{_4{m1o%Ub!naEtn|@^frU1tDnm{r-UW|!^@B8 diff --git a/connectors/vmware/doc/en/_build/html/_static/file.png b/connectors/vmware/doc/en/_build/html/_static/file.png deleted file mode 100644 index d18082e397e7e54f20721af768c4c2983258f1b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP$HyOL$D9)yc9|lc|nKf<9@eUiWd>3GuTC!a5vdfWYEazjncPj5ZQX%+1 zt8B*4=d)!cdDz4wr^#OMYfqGz$1LDFF>|#>*O?AGil(WEs?wLLy{Gj2J_@opDm%`dlax3yA*@*N$G&*ukFv>P8+2CBWO(qz zD0k1@kN>hhb1_6`&wrCswzINE(evt-5C1B^STi2@PmdKI;Vst0PQB6!2kdN diff --git a/connectors/vmware/doc/en/_build/html/_static/jquery.js b/connectors/vmware/doc/en/_build/html/_static/jquery.js deleted file mode 100644 index 7c2430802..000000000 --- a/connectors/vmware/doc/en/_build/html/_static/jquery.js +++ /dev/null @@ -1,154 +0,0 @@ -/*! - * jQuery JavaScript Library v1.4.2 - * http://jquery.com/ - * - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2010, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Sat Feb 13 22:33:48 2010 -0500 - */ -(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, -Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& -(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, -a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== -"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, -function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
          a"; -var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, -parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= -false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= -s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, -applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; -else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, -a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== -w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, -cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= -c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); -a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, -function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); -k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), -C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= -e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& -f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; -if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", -e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, -"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, -d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, -e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); -t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| -g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, -CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, -g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, -text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, -setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= -h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== -"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, -h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& -q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; -if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

          ";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); -(function(){var g=s.createElement("div");g.innerHTML="
          ";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: -function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= -{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== -"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", -d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? -a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== -1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
          ","
          "],thead:[1,"","
          "],tr:[2,"","
          "],td:[3,"","
          "],col:[2,"","
          "],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
          ","
          "];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= -c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, -wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, -prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, -this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); -return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, -""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); -return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", -""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= -c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? -c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= -function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= -Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, -"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= -a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= -a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== -"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
          ").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, -serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), -function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, -global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& -e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? -"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== -false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= -false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", -c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| -d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); -g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== -1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== -"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; -if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== -"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| -c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; -this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= -this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, -e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
          "; -a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); -c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, -d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- -f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": -"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in -e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/connectors/vmware/doc/en/_build/html/_static/minus.png b/connectors/vmware/doc/en/_build/html/_static/minus.png deleted file mode 100644 index da1c5620d10c047525a467a425abe9ff5269cfc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknK< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF diff --git a/connectors/vmware/doc/en/_build/html/_static/pygments.css b/connectors/vmware/doc/en/_build/html/_static/pygments.css deleted file mode 100644 index d79caa151..000000000 --- a/connectors/vmware/doc/en/_build/html/_static/pygments.css +++ /dev/null @@ -1,62 +0,0 @@ -.highlight .hll { background-color: #ffffcc } -.highlight { background: #eeffcc; } -.highlight .c { color: #408090; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ -.highlight .k { color: #007020; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ -.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #007020 } /* Comment.Preproc */ -.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ -.highlight .gd { color: #A00000 } /* Generic.Deleted */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #333333 } /* Generic.Output */ -.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ -.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #007020 } /* Keyword.Pseudo */ -.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #902000 } /* Keyword.Type */ -.highlight .m { color: #208050 } /* Literal.Number */ -.highlight .s { color: #4070a0 } /* Literal.String */ -.highlight .na { color: #4070a0 } /* Name.Attribute */ -.highlight .nb { color: #007020 } /* Name.Builtin */ -.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ -.highlight .no { color: #60add5 } /* Name.Constant */ -.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ -.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #007020 } /* Name.Exception */ -.highlight .nf { color: #06287e } /* Name.Function */ -.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ -.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ -.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #bb60d5 } /* Name.Variable */ -.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #208050 } /* Literal.Number.Float */ -.highlight .mh { color: #208050 } /* Literal.Number.Hex */ -.highlight .mi { color: #208050 } /* Literal.Number.Integer */ -.highlight .mo { color: #208050 } /* Literal.Number.Oct */ -.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ -.highlight .sc { color: #4070a0 } /* Literal.String.Char */ -.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ -.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ -.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ -.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ -.highlight .sx { color: #c65d09 } /* Literal.String.Other */ -.highlight .sr { color: #235388 } /* Literal.String.Regex */ -.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ -.highlight .ss { color: #517918 } /* Literal.String.Symbol */ -.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ -.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ -.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ -.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/_static/searchtools.js b/connectors/vmware/doc/en/_build/html/_static/searchtools.js deleted file mode 100644 index 663be4c90..000000000 --- a/connectors/vmware/doc/en/_build/html/_static/searchtools.js +++ /dev/null @@ -1,560 +0,0 @@ -/* - * searchtools.js_t - * ~~~~~~~~~~~~~~~~ - * - * Sphinx JavaScript utilties for the full-text search. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words, hlwords is the list of normal, unstemmed - * words. the first one is used to find the occurance, the - * latter for highlighting it. - */ - -jQuery.makeSearchSummary = function(text, keywords, hlwords) { - var textLower = text.toLowerCase(); - var start = 0; - $.each(keywords, function() { - var i = textLower.indexOf(this.toLowerCase()); - if (i > -1) - start = i; - }); - start = Math.max(start - 120, 0); - var excerpt = ((start > 0) ? '...' : '') + - $.trim(text.substr(start, 240)) + - ((start + 240 - text.length) ? '...' : ''); - var rv = $('
          ').text(excerpt); - $.each(hlwords, function() { - rv = rv.highlightText(this, 'highlighted'); - }); - return rv; -} - - -/** - * Porter Stemmer - */ -var Stemmer = function() { - - var step2list = { - ational: 'ate', - tional: 'tion', - enci: 'ence', - anci: 'ance', - izer: 'ize', - bli: 'ble', - alli: 'al', - entli: 'ent', - eli: 'e', - ousli: 'ous', - ization: 'ize', - ation: 'ate', - ator: 'ate', - alism: 'al', - iveness: 'ive', - fulness: 'ful', - ousness: 'ous', - aliti: 'al', - iviti: 'ive', - biliti: 'ble', - logi: 'log' - }; - - var step3list = { - icate: 'ic', - ative: '', - alize: 'al', - iciti: 'ic', - ical: 'ic', - ful: '', - ness: '' - }; - - var c = "[^aeiou]"; // consonant - var v = "[aeiouy]"; // vowel - var C = c + "[^aeiouy]*"; // consonant sequence - var V = v + "[aeiou]*"; // vowel sequence - - var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 - var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 - var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 - var s_v = "^(" + C + ")?" + v; // vowel in stem - - this.stemWord = function (w) { - var stem; - var suffix; - var firstch; - var origword = w; - - if (w.length < 3) - return w; - - var re; - var re2; - var re3; - var re4; - - firstch = w.substr(0,1); - if (firstch == "y") - w = firstch.toUpperCase() + w.substr(1); - - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) - w = w.replace(re,"$1$2"); - else if (re2.test(w)) - w = w.replace(re2,"$1$2"); - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); - } - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) - w = w + "e"; - else if (re3.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - else if (re4.test(w)) - w = w + "e"; - } - } - - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) - w = stem + "i"; - } - - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step2list[suffix]; - } - - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step3list[suffix]; - } - - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) - w = stem; - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) - w = stem; - } - - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) - w = stem; - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - - // and turn initial Y back to y - if (firstch == "y") - w = firstch.toLowerCase() + w.substr(1); - return w; - } -} - - -/** - * Search Module - */ -var Search = { - - _index : null, - _queued_query : null, - _pulse_status : -1, - - init : function() { - var params = $.getQueryParameters(); - if (params.q) { - var query = params.q[0]; - $('input[name="q"]')[0].value = query; - this.performSearch(query); - } - }, - - loadIndex : function(url) { - $.ajax({type: "GET", url: url, data: null, success: null, - dataType: "script", cache: true}); - }, - - setIndex : function(index) { - var q; - this._index = index; - if ((q = this._queued_query) !== null) { - this._queued_query = null; - Search.query(q); - } - }, - - hasIndex : function() { - return this._index !== null; - }, - - deferQuery : function(query) { - this._queued_query = query; - }, - - stopPulse : function() { - this._pulse_status = 0; - }, - - startPulse : function() { - if (this._pulse_status >= 0) - return; - function pulse() { - Search._pulse_status = (Search._pulse_status + 1) % 4; - var dotString = ''; - for (var i = 0; i < Search._pulse_status; i++) - dotString += '.'; - Search.dots.text(dotString); - if (Search._pulse_status > -1) - window.setTimeout(pulse, 500); - }; - pulse(); - }, - - /** - * perform a search for something - */ - performSearch : function(query) { - // create the required interface elements - this.out = $('#search-results'); - this.title = $('

          ' + _('Searching') + '

          ').appendTo(this.out); - this.dots = $('').appendTo(this.title); - this.status = $('

          ').appendTo(this.out); - this.output = $('
          '); - } - // Prettify the comment rating. - comment.pretty_rating = comment.rating + ' point' + - (comment.rating == 1 ? '' : 's'); - // Make a class (for displaying not yet moderated comments differently) - comment.css_class = comment.displayed ? '' : ' moderate'; - // Create a div for this comment. - var context = $.extend({}, opts, comment); - var div = $(renderTemplate(commentTemplate, context)); - - // If the user has voted on this comment, highlight the correct arrow. - if (comment.vote) { - var direction = (comment.vote == 1) ? 'u' : 'd'; - div.find('#' + direction + 'v' + comment.id).hide(); - div.find('#' + direction + 'u' + comment.id).show(); - } - - if (opts.moderator || comment.text != '[deleted]') { - div.find('a.reply').show(); - if (comment.proposal_diff) - div.find('#sp' + comment.id).show(); - if (opts.moderator && !comment.displayed) - div.find('#cm' + comment.id).show(); - if (opts.moderator || (opts.username == comment.username)) - div.find('#dc' + comment.id).show(); - } - return div; - } - - /** - * A simple template renderer. Placeholders such as <%id%> are replaced - * by context['id'] with items being escaped. Placeholders such as <#id#> - * are not escaped. - */ - function renderTemplate(template, context) { - var esc = $(document.createElement('div')); - - function handle(ph, escape) { - var cur = context; - $.each(ph.split('.'), function() { - cur = cur[this]; - }); - return escape ? esc.text(cur || "").html() : cur; - } - - return template.replace(/<([%#])([\w\.]*)\1>/g, function() { - return handle(arguments[2], arguments[1] == '%' ? true : false); - }); - } - - /** Flash an error message briefly. */ - function showError(message) { - $(document.createElement('div')).attr({'class': 'popup-error'}) - .append($(document.createElement('div')) - .attr({'class': 'error-message'}).text(message)) - .appendTo('body') - .fadeIn("slow") - .delay(2000) - .fadeOut("slow"); - } - - /** Add a link the user uses to open the comments popup. */ - $.fn.comment = function() { - return this.each(function() { - var id = $(this).attr('id').substring(1); - var count = COMMENT_METADATA[id]; - var title = count + ' comment' + (count == 1 ? '' : 's'); - var image = count > 0 ? opts.commentBrightImage : opts.commentImage; - var addcls = count == 0 ? ' nocomment' : ''; - $(this) - .append( - $(document.createElement('a')).attr({ - href: '#', - 'class': 'sphinx-comment-open' + addcls, - id: 'ao' + id - }) - .append($(document.createElement('img')).attr({ - src: image, - alt: 'comment', - title: title - })) - .click(function(event) { - event.preventDefault(); - show($(this).attr('id').substring(2)); - }) - ) - .append( - $(document.createElement('a')).attr({ - href: '#', - 'class': 'sphinx-comment-close hidden', - id: 'ah' + id - }) - .append($(document.createElement('img')).attr({ - src: opts.closeCommentImage, - alt: 'close', - title: 'close' - })) - .click(function(event) { - event.preventDefault(); - hide($(this).attr('id').substring(2)); - }) - ); - }); - }; - - var opts = { - processVoteURL: '/_process_vote', - addCommentURL: '/_add_comment', - getCommentsURL: '/_get_comments', - acceptCommentURL: '/_accept_comment', - deleteCommentURL: '/_delete_comment', - commentImage: '/static/_static/comment.png', - closeCommentImage: '/static/_static/comment-close.png', - loadingImage: '/static/_static/ajax-loader.gif', - commentBrightImage: '/static/_static/comment-bright.png', - upArrow: '/static/_static/up.png', - downArrow: '/static/_static/down.png', - upArrowPressed: '/static/_static/up-pressed.png', - downArrowPressed: '/static/_static/down-pressed.png', - voting: false, - moderator: false - }; - - if (typeof COMMENT_OPTIONS != "undefined") { - opts = jQuery.extend(opts, COMMENT_OPTIONS); - } - - var popupTemplate = '\ -
          \ -

          \ - Sort by:\ - best rated\ - newest\ - oldest\ -

          \ -
          Comments
          \ -
          \ - loading comments...
          \ -
            \ -
            \ -

            Add a comment\ - (markup):

            \ -
            \ - reStructured text markup: *emph*, **strong**, \ - ``code``, \ - code blocks: :: and an indented block after blank line
            \ -
            \ - \ -

            \ - \ - Propose a change ▹\ - \ - \ - Propose a change ▿\ - \ -

            \ - \ - \ - \ - \ -
            \ -
            \ -
            '; - - var commentTemplate = '\ -
            \ -
            \ -
            \ - \ - \ - \ - \ - \ - \ -
            \ -
            \ - \ - \ - \ - \ - \ - \ -
            \ -
            \ -
            \ -

            \ - <%username%>\ - <%pretty_rating%>\ - <%time.delta%>\ -

            \ -
            <#text#>
            \ -

            \ - \ - reply ▿\ - proposal ▹\ - proposal ▿\ - \ - \ -

            \ -
            \
            -<#proposal_diff#>\
            -        
            \ -
              \ -
              \ -
              \ -
              \ -
              '; - - var replyTemplate = '\ -
            • \ -
              \ -
              \ - \ - \ - \ - \ - \ -
              \ -
              \ -
            • '; - - $(document).ready(function() { - init(); - }); -})(jQuery); - -$(document).ready(function() { - // add comment anchors for all paragraphs that are commentable - $('.sphinx-has-comment').comment(); - - // highlight search words in search results - $("div.context").each(function() { - var params = $.getQueryParameters(); - var terms = (params.q) ? params.q[0].split(/\s+/) : []; - var result = $(this); - $.each(terms, function() { - result.highlightText(this.toLowerCase(), 'highlighted'); - }); - }); - - // directly open comment window if requested - var anchor = document.location.hash; - if (anchor.substring(0, 9) == '#comment-') { - $('#ao' + anchor.substring(9)).click(); - document.location.hash = '#s' + anchor.substring(9); - } -}); diff --git a/connectors/vmware/doc/en/_build/html/exploitation/index.html b/connectors/vmware/doc/en/_build/html/exploitation/index.html deleted file mode 100644 index 3cdc39ac9..000000000 --- a/connectors/vmware/doc/en/_build/html/exploitation/index.html +++ /dev/null @@ -1,2378 +0,0 @@ - - - - - - - - - - Exploitation — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - -
              -
              -
              -
              - -
              -

              Exploitation¶

              -
              -

              Centreon-esxd Presentation¶

              -
              -

              Generals Principles¶

              -

              Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter.

              -

              By default “centreon-esxd” starts at least two processes (named “handle-client” and “handle-vsphere-xxxx”) :

              -
              -
              « handle-client Â»:
              -
              Process waiting for requests of “centron-esx-client.pl” clients.
              -
              -

              Steps of operation :

              -
                -
              • A client connects.
              • -
              • The client ask an monitoring indicator on a VirtualCenter.
              • -
              • The process “handle-client” sends the request to process “handle-vsphere-xxxx”.
              • -
              • A response is sent by “handle-vsphere-xxxx” to “handle-client”.
              • -
              • The process “handle-client” sends the response to the client.
              • -
              -
              -
              « handle-vsphere-xxxx Â»:
              -
              Process responsible to connect and to keep opened a session with the VirtualCenter. To ensure quality performance, a cache of datas description is created.
              -
              -

              Then, this process gets back the VMWare indicators creating a subprocess per request.

              -

              Centreon-esxd necessitates the utilization of one (or more) VirtualCenter. It isn’t possible to get back informations of an ESX server directly.

              -

              This is a example of a fragmented architecture :

              -../_images/archi.png -
              -
              -

              Operating mode¶

              -

              The “centreon-esxd” program only works in “daemon” mode. (dans le sens où il ne peut fournir les indicateurs sans l’utilisation d’un client).

              -

              Lors de l’utilisation du plugin centreon_esx_client.pl, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans “/usr/share/centreon/lib/centreon-esxd” et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires.

              -
              -
              -

              Configuration du connecteur¶

              -

              Le daemon « centreon-esxd Â» possède un fichier de configuration « centreon_esxd.pm Â» de la forme suivante :

              -
              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',
              -                                   'password' => 'XXXXXX'}
              -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";
              -
              -

              La variable «%vsphere_server Â» permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d’avoir au moins l’entrée ‘default’.

              -

              La variable « $port Â» permet de configurer le port d’écoute du connecteur « centreon-esxd Â».

              -

              Il est aussi possible de modifier la variable « $log_mode Â» si vous souhaitez utiliser « syslog Â» au lieu d’un fichier à plat.

              -

              Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION Â», « $TIMEOUT_KILL Â», « $ TIMEOUT_VSPHERE Â» et « $TIMEOUT Â», car ils sont configurés pour une utilisation optimale.

              -
              -
              -
              -

              Optimisation de la configuration dans Centreon¶

              -

              Afin d’exploiter pleinement « centreon-esxd Â», il est recommandé d’effectuer une série d’action préalablement.

              -

              Ce connecteur permet la définition de trois modèles d’hôtes :

              -
                -
              • le modèle hôte « VMWare-VM Â» : modèle d’une machine virtuelle.
              • -
              • le modèle hôte « VMWare-ESX Â» : modèle d’un serveur ESX.
              • -
              • le modèle hôte « VMWare-VC Â» : modèle d’un virtualCenter (Ce modèle contient notamment des services pour les « datastores Â»)
              • -
              -

              Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration.

              - ----- - - - - - - - - - - - - - - - - - - - - -
              Macro NameMacro ValueRessource ou la macro doit être défini (recommandé)
              HOSTESXDHOSTIp ou nom d’hôte du serveur exécutant le daemon « centreon-esxd Â»Modèle d’hôte VMWare-* de plus bas niveau
              HOSTESXDPORTPort du daemonModèle d’hôte VMWare-* de plus bas niveau
              HOSTVCNAMENom identifiant le VirtualCenterModèle d’hôte VMWare-* de plus bas niveau
              -

              Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm Â» qui se situe normalement dans “/etc/centreon/centreon_esxd.pm” . Ce système évite la visualisation d’un mot de passe dans l’interface « centreon Â».

              -
              -

              Création d’un modèle d’hôte VMWare générique¶

              -

              Aller dans le menu configuration/host/template/, et créer un modèle d’hôte « VMWare Â». Ce modèle d’hôte sera le modèle parent pour les modèles « VMWare-VM Â», « VMWare-ESX Â» et « VMWare-VC Â».

              -

              Configurer l’ensemble des champs comme indiqué dans la documentation Centreon.

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - - - - -
              Macro NameMacro Value
              ESXDHOSTExemple: 10.30.10.30
              ESXDPORT5700 (port par défaut)
              VCNAMEdefault
              -
              -
              -

              Troubleshooting¶

              -

              Il est possible de retrouver des erreurs de ce type dans les « log Â» de « centreon-esxd Â» :

              -
              ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac...
              -
              -
              -

              Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur.

              -

              Il est nécessaire de remonter un problème dans le cas d’un trop grand nombres de déconnexion du daemon au VirtualCenter.

              -
              -
              -
              -

              Liste des contrôles¶

              -
              -

              Contrôles ESX¶

              -
              -

              CPU¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_cpuhost
              DescriptionContrôle le taux d’utilisation CPU d’un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs.
              Fonctionnement
                -
              • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéescpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100
              Interval/Retry(min)5/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlercpuhost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
              --light-perfdata(optionnel) Permet d’afficher uniquement la perfdata du CPU total 
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING80
              CRITICAL90
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              MEMOIRE¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_memhost
              Description
              -
              Contrôle le taux d’utilisation mémoire d’un serveur ESX. 3 métriques sont renvoyés :
              -
                -
              • le taux d’utilisation mémoire (en octets),
              • -
              • la taille totale de la mémoire (en octets),
              • -
              • la mémoire suralloué par la totalité des VMs (‘overhead’ en octets)
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéesused=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o
              Interval/Retry(min)20/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlermemhost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING80
              CRITICAL90
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              RESEAU¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_nethost
              Description
              -
              Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés :
              -
                -
              • le taux d’utilisation en entrée et sortie (en b/s).
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la(les) métrique(s) « traffic_* Â» est(sont) au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéestraffic_in=598016b/s traffic_out=172032b/s
              Interval/Retry(min)5/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlernethost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              --nicNom de l’interface réseau physiquevmnic0
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - - - - -
              Macro NameMacro Value
              NICNAME 
              WARNING80
              CRITICAL90
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$"
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              SWAP¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_swaphost
              Description
              -
              Contrôle le taux d’utilisation mémoire d’un serveur ESX. 2 métriques sont renvoyés :
              -
                -
              • le taux de lecture et d’écriture du swap globale de l’ensemble des machines virtuelles (en Mb/s).
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la(les) métrique(s) « swap_* Â» est(sont) au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéesswap_in=0b/s swap_out=0b/s
              Interval/Retry(min)20/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerswaphost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -w ou --warning(optionnel – Défaut : 0.8) Seuil warning en MB/s0.5
              -c ou --critical(optionnel – Défaut : 1) Seuil critique en MB/s1.5
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING0.8
              CRITICAL1
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              DATASTORES¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_datastoreshost
              Description
              -
              Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés par le datastore :
              -
                -
              • la latence totale en lecture et écriture (en ms).
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyées‘trl_LUN1’=0.00ms ‘twl_LUN1’=0.00ms ‘trl_LUN2’=0.00ms ‘twl_LUN2’=1.00ms
              Interval/Retry(min)5/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerdatastoreshost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              --filter-datastores(optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules)LUN1,LUN2
              -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms75
              -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms90
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING30
              CRITICAL50
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              COUNTVM¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_countvmhost
              Description
              -
              Contrôle le taux d’utilisation mémoire d’un serveur ESX. 1 métrique est remontée :
              -
                -
              • le nombre de machines virtuelles allumées.
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la métrique « count Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « count Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « count Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéescount=45
              Interval/Retry(min)20/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlercountvmhost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -w ou --warning(optionnel – Défaut : aucunes valeurs) Seuil warning en ms10
              -c ou --critical(optionnel – Défaut : aucunes valeurs) Seuil critique en ms15
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING10
              CRITICAL15
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              HEALTH¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_healthhost
              DescriptionContrôle l’état des sondes matériels et processeurs d’un serveur ESX.
              Fonctionnement
              -
              Remonte un état selon l’état des sondes:
              -
                -
              • “Yellow” correspond à WARNING.
              • -
              • “Red” correspond à CRITICAL.
              • -
              -
              -
              -
              Métriques renvoyées 
              Interval/Retry(min)30/1
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerhealthhost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
                
                
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              MAINTENANCE¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_maintenancehost
              DescriptionContrôle le mode de maintenance d’un serveur ESX.
              Fonctionnement
                -
              • Remonte l’état « CRITICAL » si le serveur ESX est en mode de maintenance.
              • -
              -
              Métriques renvoyées 
              Interval/Retry(min)30/1
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlermaintenancehost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
                
                
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              STATUT¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_statushost
              DescriptionContrôle l’état global d’un serveur ESX.
              Fonctionnement
                -
              • Remonte l’état « CRITICAL » si le statut du serveur ESX est en « red » .
              • -
              • Remonte l’état « WARNING » si le statut du serveur ESX est en « yellow » .
              • -
              • Remonte l’état « UNKNOWN » si le statut du serveur ESX est en « gray » .
              • -
              -
              Métriques renvoyées 
              Interval/Retry(min)30/1
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerstatushost
              -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
                
                
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -
              -

              Contrôles d’une machine virtuelle¶

              -
              -

              CPU¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_cpuvm
              DescriptionContrôle le taux d’utilisation CPU d’une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs.
              Fonctionnement
                -
              • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéescpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz
              Interval/Retry(min)5/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlercpuvm
              --vmNom de la machine virtuelle cibléemyvmname
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING80
              CRITICAL90
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              MEMOIRE¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_memvm
              Description
              -
              Contrôle le taux d’utilisation mémoire d’une machine virtuelle. 6 métriques sont renvoyés :
              -
                -
              • « used Â» : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets)
              • -
              • « size Â» : la taille totale de la mémoire allouée pour la machine virtuelle (en octets)
              • -
              • « overhead Â» : la mémoire sur-alloué (en octets)
              • -
              • « ballooning Â», « shared Â» et « active Â».
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéesusage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o
              Interval/Retry(min)20/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlermemvm
              --vmNom de la machine virtuelle cibléemyvmname
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING80
              CRITICAL90
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              DATASTORES¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_datastoresvm
              Description
              -
              Contrôle le taux d’utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore :
              -
                -
              • « riops Â» : le nombre moyen d’I/O de lectures par seconde
              • -
              • « wiops Â» : le nombre moyen d’I/O d’écritures par seconde
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si une métrique est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyées‘riops_LUN1’=0.00iops ‘wiops_LUN1’=0.27iops ‘riops_LUN2’=20.00iops ‘wiops_LUN2’=100.2iops
              Interval/Retry(min)5/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerdatastoresvm
              --vmNom de la machine virtuelle cibléemyvmname
              -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms100
              -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms150
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              WARNING100
              CRITICAL150
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              VMTOOLS¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_toolsvm
              DescriptionContrôle l’état des VMTools rattachées à une machine virtuelle.
              Fonctionnement
                -
              • Remonte l’état « WARNING » si les VMTools sont ‘toolsold’.
              • -
              • Remonte l’état « CRITICAL » si les VMTools sont ‘toolsnotrunning’ ou ‘toolsnotinstalled’.
              • -
              -
              Métriques renvoyées 
              Interval/Retry(min)20/1
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlertoolsvm
              --vmNom de la machine virtuelle cibléemyvmname
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
                
                
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              SNAPSHOTS¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_snapshotvm
              DescriptionContrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle.
              Fonctionnement
              -
              L’état dépend des paramètres du plugin :
              -
                -
              • Si « –warn Â» spécifié seul : remonte un état WARNING si un snapshost est présent.
              • -
              • Si « –crit Â» spécifié seul : remonte un état CRITICAL si un snapshost est présent.
              • -
              • Si « –warn Â» et « –older XXX Â» : remonte un état WARNING si un snapshost est présent et la date de création du -snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
              • -
              • Si « –crit Â» et « –older XXX Â» : remonte un état CRITICAL si un snapshost est présent et la date de création du -snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
              • -
              -
              -
              -
              Métriques renvoyées 
              Interval/Retry(min)20/1
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlersnapshotvm
              --vmNom de la machine virtuelle cibléemyvmname
              --warn(optionnel) Permet de spécifier un état WARNING 
              --crit(optionnel) Permet de spécifier un état CRITICAL 
              --older(optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant86400 (snapshot vieux de + 1jour)
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - -
              Macro NameMacro Value
              THRESHOLD
                -
              • -warn
              • -
              -
                
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -
              -

              Contrôle d’un datastore¶

              -
              -

              USAGE¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_datastoreusage
              Description
              -
              Contrôle le taux d’utilisation d’un datastore. 2 métriques sont renvoyés :
              -
                -
              • « used Â» : l’espace occupé par le datastore (en octets)
              • -
              • « size Â» : la taille totale allouée pour le datastore (en octets)
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéesused=506574405632o;;;0;643976658944 size=643976658944o
              Interval/Retry(min)20/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerdatastore-usage
              -e ou --esx-hostNom du datastore ciblédsname
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - - - - -
              Macro NameMacro Value
              DSNAME 
              WARNING80
              CRITICAL90
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -

              DATASTORE I/O¶

              -
              -
              Fiche d’identité¶
              - ---- - - - - - - - - - - - - - - - - - -
              Nom du plugincheck_merethis_vmware_datastorio
              Description
              -
              Contrôle le taux d’utilisation (I/O) d’un datastore. 2 métriques sont renvoyés :
              -
                -
              • « read_rate Â» : le taux d’utilisation moyen en lecture par seconde (en b/s)
              • -
              • « write_rate Â» : la taille d’utilisation moyen en écriture par seconde (en b/s)
              • -
              -
              -
              -
              Fonctionnement
                -
              • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
              • -
              • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
              • -
              • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
              • -
              -
              Métriques renvoyéesread_rate=1589248b/s write_rate=14344192b/s
              Interval/Retry(min)5/5
              -
              -
              -
              Attribut du contrôle¶
              - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
              AttributDescriptionExemple
              -uIndicateur à contrôlerdatastore-io
              -e ou --esx-hostNom du datastore ciblédsname
              -w ou --warning(optionnel – Défaut : 80) Seuil warning en kBps100
              -c ou --critical(optionnel – Défaut : 90) Seuil critique en kBps200
              -

              Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

              - ---- - - - - - - - - - - - - - -
              OptionComportement
              -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
              -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              -
              -
              -
              Création d’un service et/ou modèle de service¶
              -

              Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

              -

              Définir les macros suivante :

              - ---- - - - - - - - - - - - - - - - - -
              Macro NameMacro Value
              DSNAME 
              WARNING100
              CRITICAL150
              -
              -
              -
              Création d’une check command¶
              -

              Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

              -
              $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
              -
              -

              L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

              -
              -
              -
              -
              -
              - - -
              -
              -
              -
              -
              -

              Table Of Contents

              - - -

              Previous topic

              -

              Installation

              -

              This Page

              - - - -
              -
              -
              -
              - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/genindex.html b/connectors/vmware/doc/en/_build/html/genindex.html deleted file mode 100644 index 67f65cb2f..000000000 --- a/connectors/vmware/doc/en/_build/html/genindex.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - Index — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - -
              -
              -
              -
              - - -

              Index

              - -
              - -
              - - -
              -
              -
              -
              -
              - - - - - -
              -
              -
              -
              - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/index.html b/connectors/vmware/doc/en/_build/html/index.html deleted file mode 100644 index dcd03820a..000000000 --- a/connectors/vmware/doc/en/_build/html/index.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - Welcome to Centreon ESXD’s documentation! — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - -
              - -
              -
              -

              Table Of Contents

              - - -

              Next topic

              -

              Installation

              -

              This Page

              - - - -
              -
              -
              -
              - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/installation/index.html b/connectors/vmware/doc/en/_build/html/installation/index.html deleted file mode 100644 index 02725ef69..000000000 --- a/connectors/vmware/doc/en/_build/html/installation/index.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - - - - - Installation — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - - -
              -
              -
              -
              - -
              -

              Installation¶

              -
              -

              Prerequisites¶

              -
              -

              Software Recommandations¶

              -

              The “centreon-esxd” connector has been tested on linux systems. -Installation on other system is possible but is outside the scope of this document.

              - ---- - - - - - - - - - - - - - - - - -
              SoftwareMinimal Version
              VMWare SDK Perl5.0
              Perl5.8
              centreon-esxd1.3
              -
              -
              -

              Hardware Recommandations¶

              -

              Hardware prerequisites will vary depending on the number of monitored hosts. Without configured, no checks are done. Minimal used ressources are :

              -
                -
              • RAM : 512 Mo (May slightly increase with the number of checks).
              • -
              • CPU : same as poller server.
              • -
              -
              -
              -
              -

              Centreon-esxd Installation - centos/rhel 5 systems¶

              -
              -

              SDK Perl VMWare Installation¶

              -

              The “centreon-esxd” connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it’s the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN.

              -

              Install CPAN prerequisites

              -
              root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel
              -root # yum install perl-XML-LibXML perl-Crypt-SSLeay
              -
              -root # cpan install Class::MethodMaker
              -root # cpan install LWP
              -root # cpan install Net::SSLeay
              -root # cpan install LWP::Protocol::https
              -root # cpan install SOAP::Lite
              -
              -root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
              -root # tar zxvf UUID-0.04.tar.gz
              -root # cd UUID-0.04
              -root # perl Makefile.PL
              -root # make && make install
              -
              -
              -

              All SDK prerequisites are installed.

              -

              Download the last version on the VMWare website (SDK VMWare) (choose the file correponding to your architecture)

              -

              Install VMWare Perl SDK:

              -
              root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
              -root # cd vmware-vsphere-cli-distrib
              -root # perl Makefile.pl
              -root # make && make install
              -
              -
              -
              -
              -

              Addtionnal Modules Installation¶

              -

              Some features require additionnal prerequisites.

              -

              To send data to a syslog daemon, the ” Unix::Syslog” must be installed

              -
              root # cpan install Unix::Syslog
              -
              -
              -

              To check a virtual server snapshots date, the “DateTime::Format::ISO8601” is required (be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous)

              -
              root # cpan install DateTime
              -root # cpan install DateTime::Format::ISO8601
              -root # o conf make /usr/bin/make
              -root # o conf commit
              -
              -
              -

              Reboot your system to complete.

              -
              -
              -

              centreon-esxd Installation¶

              -

              Download « centreon-esxd » archive, then install

              -
              root # tar zxvf centreon-esxd-1.X.tar.gz
              -root # cd centreon-esxd-1.X
              -root # cp centreon_esxd /usr/bin/
              -
              -root # mkdir -p /etc/centreon
              -root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
              -root # cp centreon_esxd-init /etc/init.d/centreon_esxd
              -
              -root # mkdir -p /usr/share/centreon/lib/centreon-esxd
              -root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
              -
              -
              -

              Configure “centreon-esxd” daemon to start at boot

              -
              root # chkconfig --level 2345 centreon_esxd on
              -
              -
              -

              “centreon_esx_client.pl” is the corresponding nagios plugin.

              -
              -
              -
              -

              Centreon-esxd Installation - centos/rhel 6 systems¶

              -
              -

              SDK Perl VMWare Installation¶

              -

              The “centreon-esxd” connector uses SDK Perl VMWare for its operation. So we install it. To do this, we begin by install CPAN, it’s the name of a Perl module who improves the download, the installation, the upgrade and the maintenance of others Perl modules who are archived on the CPAN.

              -

              Install CPAN prerequisites

              -
              root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel
              -root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite
              -
              -root # cpan install Test::More
              -root # cpan install LWP
              -root # cpan install Net::SSLeay
              -root # cpan install LWP::Protocol::https
              -
              -root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
              -root # tar zxvf UUID-0.04.tar.gz
              -root # cd UUID-0.04
              -root # perl Makefile.PL
              -root # make && make install
              -
              -
              -

              All SDK prerequisites are installed.

              -

              Download the last version on the VMWare website (SDK VMWare) (choose the file correponding to your architecture)

              -

              Install VMWare Perl SDK:

              -
              root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
              -root # cd vmware-vsphere-cli-distrib
              -root # perl Makefile.pl
              -root # make && make install
              -
              -
              -
              -
              -

              Addtionnal Modules Installation¶

              -

              Some features require additionnal prerequisites.

              -

              To send data to a syslog daemon, the ” Unix::Syslog” must be installed

              -
              root # cpan install Unix::Syslog
              -
              -
              -

              To check a virtual server snapshots date, the “DateTime::Format::ISO8601” is required (be advise that this module has a lot of CPAN dependencies and may need a full Perl update. This update is hazardous)

              -
              root # cpan install DateTime
              -root # cpan install DateTime::Format::ISO8601
              -root # o conf make /usr/bin/make
              -root # o conf commit
              -
              -
              -

              Reboot your system to complete.

              -
              -
              -

              centreon-esxd Installation¶

              -

              Download « centreon-esxd » archive, then install

              -
              root # tar zxvf centreon-esxd-1.X.tar.gz
              -root # cd centreon-esxd-1.X
              -root # cp centreon_esxd /usr/bin/
              -
              -root # mkdir -p /etc/centreon
              -root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
              -root # cp centreon_esxd-init /etc/init.d/centreon_esxd
              -
              -root # mkdir -p /usr/share/centreon/lib/centreon-esxd
              -root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
              -
              -
              -

              Configure “centreon-esxd” daemon to start at boot

              -
              root # chkconfig --level 2345 centreon_esxd on
              -
              -
              -

              “centreon_esx_client.pl” is the corresponding nagios plugin.

              -
              -
              -
              - - -
              -
              -
              - -
              -
              - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/objects.inv b/connectors/vmware/doc/en/_build/html/objects.inv deleted file mode 100644 index 6b9e7d70341d5f6891429e463885b3a060ed17b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~KjbN*1L8MO}j< zT!0c`5JgrBhI$4-Zb(L|LQ!gNVrE`SYLP;InnFoNX0bwAW=^UCkWS9eEhtJYE>2BR zC@s#+OIN7M$xPDYs - - - - - - - Search — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - - - - -
              -
              -
              -
              - -

              Search

              -
              - -

              - Please activate JavaScript to enable the search - functionality. -

              -
              -

              - From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing fewer words won't appear in the result list. -

              -
              - - - -
              - -
              - -
              - -
              -
              -
              -
              -
              -
              -
              -
              -
              - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/en/_build/html/searchindex.js b/connectors/vmware/doc/en/_build/html/searchindex.js deleted file mode 100644 index d83bedd88..000000000 --- a/connectors/vmware/doc/en/_build/html/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({objects:{},terms:{"2iop":2,code:[],check_merethis_vmware_datastorio:2,trl_lun2:2,librairi:2,global:2,all:1,yellow:2,"nomm\u00e9":[],"\u00e9clat\u00e9":[],fourni:[],row:[],indicateur:2,depend:1,"27iop":2,send:[1,2],init:1,program:2,"surallou\u00e9":2,aux:2,sent:2,valeur:2,"d\u00e9j\u00e0":2,sond:2,"valid\u00e9":[],"22743040o":2,util:2,hardwar:1,sont:2,garder:[],check_merethis_vmware_nethost:2,vmtool:2,level:1,necessit:2,list:[0,2],"d\u00e9marrag":[],servic:2,x86_64:1,visualis:2,"362747904o":2,"derni\u00e8r":[],direct:2,syslog:[1,2],second:2,pass:2,download:1,port:2,vmware:[1,2],supervis:[],"_hostvcnam":2,section:[],quelqu:2,statushost:2,riops_lun1:2,communiqu:2,version:1,sur:2,peuvent:2,net:1,cela:[],"charg\u00e9":[],full:1,"contr\u00f4ler":2,voici:[],snapshost:2,bodi:[],solari:[],"fonctionnalit\u00e9":[],modifi:2,valu:2,"m\u00eame":[],"tr\u00e8":[],search:[0,1],"v\u00e9rific":[],"r\u00e9cup\u00e8r":[],beaucoup:[],"g\u00e9n\u00e9riqu":2,datetim:1,action:2,que:2,environn:[],"risqu\u00e9":[],modul:[0,1,2],souhaitez:2,ask:2,unix:[1,2],instal:[0,1,2],total:2,"1773761536o":2,commun:2,lwp:1,upgrad:1,perl:[1,2],connector:1,latenc:2,overhead:2,rhel:[0,1],scope:1,vcenter:2,addtionn:1,type:2,swap:2,ensuit:2,riop:2,check_merethis_vmware_cpuhost:2,log_daemon:2,filtrer:2,check_merethis_vmware_datastoresvm:2,iso8601:1,warn:2,twl_lun2:2,twl_lun1:2,moin:2,recommand:1,cach:2,"rattach\u00e9":2,must:1,augment:[],car:2,work:2,uniqu:2,pour:2,minimum:[],client:2,taux:2,nagio:1,root:1,"506574405632o":2,tar:1,process:2,requi:[],share:[1,2],check_merethis_vmware_swaphost:2,templat:2,critic:2,unzip:1,check_merethis_vmware_healthhost:2,"r\u00e9pons":[],traffic_out:2,suivant:2,gcc:1,refresh_keeper_sess:2,"totalit\u00e9":2,rapport:2,write:[],toolsnotinstal:2,optimal:2,memoir:2,updat:1,xxxx:2,"r\u00e9sultat":2,swap_in:2,mac:2,attent:[],mai:[1,2],datastoresvm:2,datastor:2,data:[1,2],"remont\u00e9":2,souci:[],welcom:0,permet:2,light:2,timeout_kil:2,correspond:[1,2],allon:[],issu:2,inform:2,ensembl:2,order:2,"m\u00e9moir":2,"d\u00e9faut":2,offici:[],peut:2,increas:1,"00mhz":2,afin:2,"h\u00e9bergeant":2,kbp:2,jnh:1,"r\u00e9colter":2,reseau:2,"_servicethreshold":2,uuid:1,window:[],"\u00e9critur":2,memhost:2,nom:2,non:[],"syst\u00e8m":2,handl:2,qualiti:2,dan:[0,2],taill:2,devel:1,"\u00e9galement":2,effectu:2,autr:[],optionnel:2,nou:[],son:[],"1jour":2,check_merethis_vmware_snapshotvm:2,critiqu:2,name:[1,2],aucun:2,troubleshoot:2,"g\u00e9n\u00e9raux":[],temps_cour:2,"install\u00e9":[],check_merethis_vmware_datastoreusag:2,mode:2,timeout:2,done:1,cett:2,espac:2,ouvr:2,"cr\u00e9er":2,connect:2,"r\u00e9seau":2,distrib:1,our:2,"probl\u00e8m":2,variabl:2,respectiv:[],mettr:[],reboot:1,content:0,"\u00e9cout":2,health:2,traffic_in:2,centreon_esxd:[1,2],red:2,serveur:2,"contr\u00f4l":[0,2],check_merethis_vmware_maintenancehost:2,e2fsprog:1,hazard:1,qui:2,org:1,selon:2,contient:2,libuuid:1,openssl:1,keep:2,filter:2,liaison:2,yum:1,isn:2,outsid:1,unknown:2,principl:2,poller:1,processeur:2,oper:[1,2],softwar:1,"pr\u00e9sent\u00e9":[],check_merethis_vmware_countvmhost:2,mise:[],"pr\u00e9":[],number:1,votr:[],affich:2,donc:[],"indiqu\u00e9":2,crit:2,virtualcent:2,tou:2,open:2,ont:2,size:2,fonctionn:2,start:[1,2],"_hostesxdport":2,mkdir:1,system:[0,1],least:2,trl_lun1:2,nethost:2,"final":2,shell:[],option:2,"poss\u00e8d":2,cpu2:2,cpu3:2,specifi:2,cpu1:2,"d\u00e9pend":2,date:[1,2],virtuel:2,centreon_esx_cli:[1,2],ssl3_get_record:2,provid:2,"00iop":2,older:2,wiops_lun2:2,wiops_lun1:2,timeout_vspher:2,ressourc:[1,2],sera:2,"red\u00e9marr":[],cpu_total_mhz:2,"acc\u00e8":2,ram:1,aussi:2,myvmnam:2,titl:[],"56196403200o":2,wiop:2,tabl:0,need:1,requisit:[],optimis:[0,2],troi:2,jour:[],lib:[1,2],min:2,check:[1,2],hostvcnam:2,"d\u00e9connexion":2,libpath:2,exampl:2,fonction:[],deux:[],soap:[1,2],simplifi:2,begin:1,macro:2,"sp\u00e9cifier":2,swaphost:2,usernam:2,"configur\u00e9":2,who:1,plat:2,doit:2,dessu:2,maintenancehost:2,cpu0:2,"v\u00e9rifier":[],toolsnotrun:2,"class":1,charg:2,countvm:2,url:2,request:2,snapshot:[1,2],"_servicedsnam":2,"68705865728o":2,"\u00e9tat":2,vcname:2,"n\u00e9cessair":2,"cr\u00e9\u00e9":[],text:[],subprocess:2,directli:2,session:2,threshold:2,identifi:2,trop:2,retrouv:2,xml:1,fichier:2,onli:2,menu:2,configur:[0,1,2],activ:2,"cr\u00e9ant":[],"cr\u00e9ation":2,"70148096o":2,"diff\u00e9rent":2,"s\u00e9par\u00e9":2,yml:[],count:2,get:2,centron:2,cpuvm:2,ssl:2,mainten:[1,2],"pr\u00eat":[],"t\u00e9l\u00e9chargement":[],champ:2,vsphere_serv:2,esxd:[0,1,2],"172032b":2,"2147483648o":2,requir:1,snapshotvm:2,grai:2,bad:2,write_r:2,"\u00e9vite":2,"caract\u00e8r":2,swap_out:2,riops_lun2:2,"643976658944o":2,"_servicecrit":2,"recommand\u00e9":2,respons:2,fail:2,sen:2,xxxxx:2,sorti:2,centreon:[0,1,2],nombr:2,vari:1,vont:2,"_servicewarn":2,gener:2,attribut:2,parent:2,check_merethis_vmware_memhost:2,pourcentag:2,comm:2,avon:[],cli:1,last:1,plugin:[1,2],"sp\u00e9cifi\u00e9":2,etc:[1,2],monitor:[1,2],erreur:2,rend:[],improv:1,login:2,com:[],pre:[],"d\u00e9conseill\u00e9":2,makefil:1,"d\u00e9finit":2,perfdata:2,exploit:[0,2],"d\u00e9finir":2,linux:1,connexion:[],aller:2,been:1,json:[],wait:2,"pr\u00e9sent":2,difficil:[],datastoreshost:2,cpu_tot:2,xxx:2,"identit\u00e9":2,demand:[],viperltoolkit:[],toolsvm:2,present:[0,2],correpond:1,"entr\u00e9":2,"ais\u00e9":[],"_hostesxdhost":2,error:2,"1408f119":2,stdout:2,envoy:[],expat:1,"4561920o":2,"allum\u00e9":2,"00m":2,vou:2,libxml:1,archiv:1,cento:[0,1],conf:1,chkconfig:1,situ:2,par:2,develop:[],log_crit:2,minim:1,perform:2,make:[1,2],memvm:2,same:1,"pr\u00e9senc":2,fragment:2,"ex\u00e9cut":2,"imp\u00e9rativ":[],traiter:2,grand:2,lite:1,document:[0,1,2],complet:1,http:[1,2],statut:2,nic:2,"d\u00e9fini":2,nicnam:2,vieux:2,moyen:2,center:2,"h\u00f4te":2,"allou\u00e9":2,notr:[],"r\u00e9cup\u00e9rer":[],traffic_:2,without:1,command:2,thi:[1,2],choos:1,san:2,programm:[],"g\u00e9n\u00e8re":2,protocol:[1,2],physiqu:2,tcp:2,indic:[0,2],processu:[],ayant:[],connecteur:2,bit:[],"renvoy\u00e9":2,site:[],virgul:2,toolsold:2,exempl:2,"cibl\u00e9":2,bloc:[],log_facil:2,enfin:[],"bas\u00e9":2,adress:2,esxdhost:2,bin:1,advis:1,format:1,read:2,mot:2,cpan:[1,2],remont:2,check_merethis_vmware_datastoreshost:2,healthhost:2,password:2,daemon:[1,2],header:[],fournir:2,officiel:[],dsname:2,noth:2,collect:[],princip:[],index:0,"pr\u00e9alabl":2,page:0,"r\u00f4le":[],vsphere:[1,2],besoin:2,swap_:2,interv:2,seuil:2,some:1,back:2,"14344192b":2,log_mod:2,hostesxdhost:2,bloqu:2,server:[1,2],"n\u00e9cessit":[],ouvert:[],tmp:2,est:2,"mat\u00e9riel":2,octet:2,per:2,esx:2,retri:2,xxxxxx:2,avoir:2,minimal:[],machin:2,plu:2,sensibl:[],ancien:2,usag:2,host:[1,2],prerequisit:[0,1],"test\u00e9":[],wget:1,"\u00eatre":2,column:[],slightli:1,commit:1,"donn\u00e9":[],zxvf:1,routin:2,read_rat:2,additionn:1,www:[],two:2,lier:2,"archiv\u00e9":[],sou:[],retourn:2,lieu:2,ensur:2,mymeta:[],your:1,websit:1,testvc:2,log:2,plusieur:[],support:[],logiciel:[],lor:2,esx1:2,interfac:2,author:1,lot:1,comport:2,"1589248b":2,methodmak:1,usr:[1,2],lun2:2,lun1:2,pleinement:2,form:2,link:[],cpuhost:2,sdk:[1,2],info:2,vive:[],temp:2,possibl:[1,2],"default":2,avec:2,record:2,"cha\u00een":2,notam:2,step:2,fich:2,more:[1,2],vmnic0:2,featur:1,"s\u00e9rie":2,creat:2,user1:2,certain:[],utilis:2,decrypt:2,lectur:2,"m\u00e9triqu":2,file:[1,2],dessou:2,"mod\u00e8l":2,hostesxdport:2,commenc:[],"occup\u00e9":2,courant:2,check_merethis_vmware_statushost:2,crypt:1,seul:2,boot:1,virtual:[1,2],other:1,"_servicenicnam":2,normal:2,viell:2,test:[1,2],snaphost:2,architectur:[1,2],countvmhost:2,check_merethis_vmware_toolsvm:2,cpu0_mhz:2,hostaddress:2,"param\u00e8tr":2,check_merethis_vmware_cpuvm:2,balloon:2,lanc:[],niveau:2,exclu:[],ssleai:1,descript:2,check_merethis_vmware_memvm:2,"598016b":2,esxdport:2,"t\u00e9l\u00e9charger":[],cpu:[1,2]},objtypes:{},titles:["Welcome to Centreon ESXD’s documentation!","Installation","Exploitation"],objnames:{},filenames:["index","installation/index","exploitation/index"]}) \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/doctrees/environment.pickle b/connectors/vmware/doc/fr/_build/doctrees/environment.pickle deleted file mode 100644 index 22474718113e27fd68404a8b0bec9516aeb1207a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43441 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 @FVtA4N)u`}jcjRX9f{I`+cytEA*OL-dG2r6 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

              9{h2h~F;9n>s36#Fou4+B9-Yr#>{ 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 E2V%GDcK`qY diff --git a/connectors/vmware/doc/fr/_build/doctrees/index.doctree b/connectors/vmware/doc/fr/_build/doctrees/index.doctree deleted file mode 100644 index 62710a3d7f8535f68e49ca783f066598b558d2e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5558 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 K9`IWq%={nn1=#-p diff --git a/connectors/vmware/doc/fr/_build/html/.buildinfo b/connectors/vmware/doc/fr/_build/html/.buildinfo deleted file mode 100644 index cd98838b0..000000000 --- a/connectors/vmware/doc/fr/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 5c34505a03d196bacf5235352ea2ec0d -tags: a205e9ed8462ae86fdd2f73488852ba9 diff --git a/connectors/vmware/doc/fr/_build/html/_images/archi.png b/connectors/vmware/doc/fr/_build/html/_images/archi.png deleted file mode 100644 index 82dca91fec4159d8be96155e65412aa0fd645059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29775 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 diff --git a/connectors/vmware/doc/fr/_build/html/_sources/exploitation/index.txt b/connectors/vmware/doc/fr/_build/html/_sources/exploitation/index.txt deleted file mode 100644 index c5657eb15..000000000 --- a/connectors/vmware/doc/fr/_build/html/_sources/exploitation/index.txt +++ /dev/null @@ -1,1384 +0,0 @@ -============ -Exploitation -============ - -Présentation de Centreon-esxd ------------------------------ - -Principes Généraux -`````````````````` - -Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. - -Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : - -*« handle-client »*: - *Processus en attente des demandes des clients « centreon_esx_client.pl ».* - -Voici le fonctionnement : - -- Un client se connecte. -- Le client demande un indicateur de supervision sur un VirtualCenter. -- Le processus « handle-client » fourni cette demande au processus « handle-vsphere-xxxx ». -- Une réponse est fournie par « handle-vsphere-xxxx » à « handle-client ». -- Le processus « handle-client » fourni la réponse au client. - -*« handle-vsphere-xxxx »*: - *Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).* - -Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. - -Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter. Il n'est pas possible de récupérer les informations d'un serveur ESX directement. - -Voici un exemple d'architecture éclaté : - -.. image:: ../images/archi.png - -Mode de fonctionnement -`````````````````````` -Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). - -Lors de l'utilisation du plugin *centreon_esx_client.pl*, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans *"/usr/share/centreon/lib/centreon-esxd"* et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires. - -Configuration du connecteur -``````````````````````````` -Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - - 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', - 'password' => 'XXXXXX'} - 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"; - -La variable «%vsphere_server » permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d'avoir au moins l'entrée 'default'. - -La variable « $port » permet de configurer le port d'écoute du connecteur « centreon-esxd ». - -Il est aussi possible de modifier la variable « $log_mode » si vous souhaitez utiliser « syslog » au lieu d'un fichier à plat. - -Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION », « $TIMEOUT_KILL », « $ TIMEOUT_VSPHERE » et « $TIMEOUT », car ils sont configurés pour une utilisation optimale. - - -Optimisation de la configuration dans Centreon ----------------------------------------------- - -Afin d'exploiter pleinement « centreon-esxd », il est recommandé d'effectuer une série d'action préalablement. - -Ce connecteur permet la définition de trois modèles d'hôtes : - -- le modèle hôte « VMWare-VM » : modèle d'une machine virtuelle. -- le modèle hôte « VMWare-ESX » : modèle d'un serveur ESX. -- le modèle hôte « VMWare-VC » : modèle d'un virtualCenter (Ce modèle contient notamment des services pour les « datastores ») - -Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration. - -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| Macro Name | Macro Value | Ressource ou la macro doit être défini (recommandé) | -| | | | -+====================+===================================================================+================================================================+ -| HOSTESXDHOST | Ip ou nom d'hôte du serveur exécutant le daemon « centreon-esxd » | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTESXDPORT | Port du daemon | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ -| HOSTVCNAME | Nom identifiant le VirtualCenter | Modèle d'hôte VMWare-* de plus bas niveau | -+--------------------+-------------------------------------------------------------------+----------------------------------------------------------------+ - -Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm » qui se situe normalement dans "*/etc/centreon/centreon_esxd.pm*" . Ce système évite la visualisation d'un mot de passe dans l'interface « centreon ». - - -Création d'un modèle d'hôte VMWare générique -```````````````````````````````````````````` - -Aller dans le menu configuration/host/template/, et créer un modèle d'hôte « VMWare ». Ce modèle d'hôte sera le modèle parent pour les modèles « VMWare-VM », « VMWare-ESX » et « VMWare-VC ». - -Configurer l'ensemble des champs comme indiqué dans la documentation Centreon. - -Définir les macros suivante : - -+---------------------+-------------------------------------------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+===================================================================+ -| ESXDHOST | Exemple: 10.30.10.30 | -+---------------------+-------------------------------------------------------------------+ -| ESXDPORT | 5700 (port par défaut) | -+---------------------+-------------------------------------------------------------------+ -| VCNAME | default | -+---------------------+-------------------------------------------------------------------+ - -Troubleshooting -``````````````` - -Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: - - ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... - -Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. - -Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. - - -Liste des contrôles -------------------- - -Contrôles ESX -````````````` -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+===========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuhost | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--light-perfdata``\ | (optionnel) Permet d'afficher uniquement la perfdata du CPU total |   | -+---------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 3 métriques sont renvoyés : | -| | - le taux d'utilisation mémoire (en octets), | -| | - la taille totale de la mémoire (en octets), | -| | - la mémoire suralloué par la totalité des VMs ('overhead' en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memhost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -RESEAU -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_nethost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux d'utilisation en entrée et sortie (en b/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « traffic_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « traffic_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | traffic_in=598016b/s traffic_out=172032b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | nethost | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--nic``\ | Nom de l'interface réseau physique | vmnic0 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| NICNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$" - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -SWAP -'''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_swaphost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 2 métriques sont renvoyés : | -| | - le taux de lecture et d'écriture du swap globale de l'ensemble des machines virtuelles (en Mb/s). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) « swap_* » est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) « swap_* » est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | swap_in=0b/s swap_out=0b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | swaphost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 0.8) Seuil warning en MB/s | 0.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 1) Seuil critique en MB/s | 1.5 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 0.8 | -+---------------------+--------------------------------+ -| CRITICAL | 1 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreshost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'une interface réseau physique d'un serveur ESX. 2 métriques sont renvoyés par le datastore : | -| | - la latence totale en lecture et écriture (en ms). | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'trl_LUN1'=0.00ms 'twl_LUN1'=0.00ms 'trl_LUN2'=0.00ms 'twl_LUN2'=1.00ms | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+============================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoreshost | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--filter-datastores``\ | (optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules) | LUN1,LUN2 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 75 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 90 | -+----------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 30 | -+---------------------+--------------------------------+ -| CRITICAL | 50 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -COUNTVM -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_countvmhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'un serveur ESX. 1 métrique est remontée : | -| | - le nombre de machines virtuelles allumées. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « count » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « count » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « count » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | count=45 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | countvmhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes valeurs) Seuil warning en ms | 10 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes valeurs) Seuil critique en ms | 15 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 10 | -+---------------------+--------------------------------+ -| CRITICAL | 15 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -HEALTH -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_healthhost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des sondes matériels et processeurs d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | Remonte un état selon l'état des sondes: | -| | - "Yellow" correspond à WARNING. | -| | - "Red" correspond à CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | healthhost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MAINTENANCE -''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_maintenancehost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le mode de maintenance d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le serveur ESX est en mode de maintenance. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | maintenancehost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -STATUT -'''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_statushost | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état global d'un serveur ESX. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « CRITICAL » si le statut du serveur ESX est en « red » . | -| | - Remonte l'état « WARNING » si le statut du serveur ESX est en « yellow » . | -| | - Remonte l'état « UNKNOWN » si le statut du serveur ESX est en « gray » . | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 30/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | statushost | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du serveur ESX ciblé | esx1.test.fr | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôles d'une machine virtuelle -````````````````````````````````` - -CPU -''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_cpuvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation CPU d'une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « cpu_total » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « cpu_total » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « cpu_total » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | cpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | cpuvm | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+--------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -MEMOIRE -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_memvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation mémoire d'une machine virtuelle. 6 métriques sont renvoyés : | -| | - « used » : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets) | -| | - « size » : la taille totale de la mémoire allouée pour la machine virtuelle (en octets) | -| | - « overhead » : la mémoire sur-alloué (en octets) | -| | - « ballooning », « shared » et « active ». | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | usage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | memvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORES -'''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoresvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore : | -| | - « riops » : le nombre moyen d'I/O de lectures par seconde | -| | - « wiops » : le nombre moyen d'I/O d'écritures par seconde | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si une métrique est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | 'riops_LUN1'=0.00iops 'wiops_LUN1'=0.27iops 'riops_LUN2'=20.00iops 'wiops_LUN2'=100.2iops | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+==========================+====================================================================================+================================================================+ -| -u | Indicateur à contrôler | datastoresvm | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : aucunes) Seuil warning en ms | 100 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : aucunes) Seuil critique en ms | 150 | -+--------------------------+------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - -VMTOOLS -''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_toolsvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle l'état des VMTools rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte l'état « WARNING » si les VMTools sont 'toolsold'. | -| | - Remonte l'état « CRITICAL » si les VMTools sont 'toolsnotrunning' ou 'toolsnotinstalled'. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | toolsvm | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| | | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -SNAPSHOTS -''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_snapshotvm | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | L'état dépend des paramètres du plugin : | -| | - Si « --warn » spécifié seul : remonte un état WARNING si un snapshost est présent. | -| | - Si « --crit » spécifié seul : remonte un état CRITICAL si un snapshost est présent. | -| | - Si « --warn » et « --older XXX » : remonte un état WARNING si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -| | - Si « --crit » et « --older XXX » : remonte un état CRITICAL si un snapshost est présent et la date de création du | -| | snapshot le plus ancien est plus vielle que « temps_courant – XXX » | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/1 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+====================+==========================================================================================+================================================================+ -| -u | Indicateur à contrôler | snapshotvm | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--vm``\ | Nom de la machine virtuelle ciblée | myvmname | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--warn``\ | (optionnel) Permet de spécifier un état WARNING | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--crit``\ | (optionnel) Permet de spécifier un état CRITICAL | | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ -| \ ``--older``\ | (optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant | 86400 (snapshot vieux de + 1jour) | -+--------------------+------------------------------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| THRESHOLD | - -warn | -+---------------------+--------------------------------+ -| | | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -Contrôle d'un datastore -``````````````````````` - -USAGE -''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastoreusage | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation d'un datastore. 2 métriques sont renvoyés : | -| | - « used » : l'espace occupé par le datastore (en octets) | -| | - « size » : la taille totale allouée pour le datastore (en octets) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | used=506574405632o;;;0;643976658944 size=643976658944o | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 20/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-usage | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en pourcentage | 75 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en pourcentage | 90 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 80 | -+---------------------+--------------------------------+ -| CRITICAL | 90 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - -DATASTORE I/O -''''''''''''' - -Fiche d'identité -................ - -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Nom du plugin** | check_merethis_vmware_datastorio | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Description** | Contrôle le taux d'utilisation (I/O) d'un datastore. 2 métriques sont renvoyés : | -| | - « read_rate » : le taux d'utilisation moyen en lecture par seconde (en b/s) | -| | - « write_rate » : la taille d'utilisation moyen en écriture par seconde (en b/s) | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Fonctionnement** | - Remonte un état OK si la métrique « used » est en dessous du seuil WARNING. | -| | - Remonte un état WARNING si la métrique « used » est en dessous du seuil CRITICAL et au dessus du seuil WARNING. | -| | - Remonte un état CRITICAL si la métrique « used » est au dessus du seuil CRITICAL. | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Métriques renvoyées** | read_rate=1589248b/s write_rate=14344192b/s | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Interval/Retry(min)** | 5/5 | -+----------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ - -Attribut du contrôle -.................... - -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| Attribut | Description | Exemple | -| | | | -+=========================+=====================================================================+================================================================+ -| -u | Indicateur à contrôler | datastore-io | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -e ou \ ``--esx-host``\ | Nom du datastore ciblé | dsname | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -w ou \ ``--warning``\ | (optionnel – Défaut : 80) Seuil warning en kBps | 100 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ -| -c ou \ ``--critical``\ | (optionnel – Défaut : 90) Seuil critique en kBps | 200 | -+-------------------------+---------------------------------------------------------------------+----------------------------------------------------------------+ - -Le plugin a également besoin des informations sur le daemon « centreon-esxd ». - - -+---------------------+-----------------------------------------------------------------------------+ -| Option | Comportement | -| | | -+=====================+=============================================================================+ -| -H | IP ou adresse du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ -| -P | (optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd » | -+---------------------+-----------------------------------------------------------------------------+ - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - - -Création d'un service et/ou modèle de service -............................................. - -Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique). - - -Définir les macros suivante : - -+---------------------+--------------------------------+ -| Macro Name | Macro Value | -| | | -+=====================+================================+ -| DSNAME | | -+---------------------+--------------------------------+ -| WARNING | 100 | -+---------------------+--------------------------------+ -| CRITICAL | 150 | -+---------------------+--------------------------------+ - -Création d'une check command -............................ - -Afin de simplifier l'utilisation de ce contrôle, il est recommandé de créer la check command suivante :: - - $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ - -L'ensemble des attributs sont déjà défini dans le modèle d'hôte et/ou hôte, et modèle de service et/ou service. - - diff --git a/connectors/vmware/doc/fr/_build/html/_sources/index.txt b/connectors/vmware/doc/fr/_build/html/_sources/index.txt deleted file mode 100644 index 8f840209e..000000000 --- a/connectors/vmware/doc/fr/_build/html/_sources/index.txt +++ /dev/null @@ -1,24 +0,0 @@ -.. Centreon ESXD documentation master file, created by - sphinx-quickstart on Mon Apr 22 11:17:38 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Centreon ESXD's documentation! -========================================= - -Contents: - -.. toctree:: - :maxdepth: 2 - - installation/index - exploitation/index - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/connectors/vmware/doc/fr/_build/html/_sources/installation/index.txt b/connectors/vmware/doc/fr/_build/html/_sources/installation/index.txt deleted file mode 100644 index 3534d2c3c..000000000 --- a/connectors/vmware/doc/fr/_build/html/_sources/installation/index.txt +++ /dev/null @@ -1,191 +0,0 @@ -============ -Installation -============ - -Pré-Requis -========== - -Préconisations logicielles -`````````````````````````` - -Le connecteur "centreon-esxd" est testé et validé sur des environnements Linux. -L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Solaris, Windows, ...). - -==================== ===================== -Logiciels Version minimum -==================== ===================== -VMWare SDK Perl 5.0 -Perl 5.8 -centreon-esxd 1.3 -==================== ===================== - -Préconisations matérielles -`````````````````````````` - -Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n'effectue aucunes vérifications. Les ressources minimales sont de : - -* mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). - -* CPU : même pré-requis que pour le serveur de collecte. - -Installation de centreon-esxd - Environnement centos/rhel 5 -=========================================================== - -Installation du SDK Perl VMWare -``````````````````````````````` - -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. - - -Installer les pré-requis CPAN:: - - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay - - root # cpan install Class::MethodMaker - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https - root # cpan install SOAP::Lite - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install - -Nous avons notre environnement prêt pour l'installation du SDK VMWare. - -Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_). - -Installer le SDK Perl VMWare:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install - -Installation de modules complémentaires -``````````````````````````````````````` - -Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : - -Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: - - root # cpan install Unix::Syslog - -Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Ensuite redémarrer votre système. - -Installation de centreon-esxd -````````````````````````````` - -Télécharger l'archive de « centreon-esxd ». - -Installer les fichiers:: - - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ - -Activer le daemon « centreon-esxd » au démarrage:: - - root # chkconfig --level 2345 centreon_esxd on - - -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* - -Installation de centreon-esxd - Environnement centos/rhel 6 -=========================================================== - -Installation du sdk Perl VMWare -``````````````````````````````` - -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. - -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer. Pour cela nous allons commencer par installer CPAN qui est le nom d'un module Perl qui rend aisés le téléchargement, l'installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN. - -Installer les pré-requis CPAN:: - - root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel - root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite - - root # cpan install Test::More - root # cpan install LWP - root # cpan install Net::SSLeay - root # cpan install LWP::Protocol::https - - root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz - root # tar zxvf UUID-0.04.tar.gz - root # cd UUID-0.04 - root # perl Makefile.PL - root # make && make install - -Nous avons notre environnement prêt pour l'installation du SDK VMWare. - -Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (`SDK VMWare `_) - -Installer le SDK Perl VMWare:: - - root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz - root # cd vmware-vsphere-cli-distrib - root # perl Makefile.pl - root # make && make install - -Installation de modules complémentaires -``````````````````````````````````````` - -Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd : - -Pour envoyer les logs au daemon « syslog », il est nécessaire d'installer le module « Unix::Syslog »:: - - root # cpan install Unix::Syslog - -Pour vérifier la date des snapshots d'une machine virtuelle, il est nécessaire d'installer le module « DateTime::Format::ISO8601 » ( **ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl ». Cette mise à jour est très risqué** ):: - - root # cpan install DateTime - root # cpan install DateTime::Format::ISO8601 - root # o conf make /usr/bin/make - root # o conf commit - -Ensuite redémarrer votre système. - -Installation de centreon-esxd -````````````````````````````` - -Télécharger l'archive de « centreon-esxd ». - -Installer les fichiers:: - - root # tar zxvf centreon-esxd-1.X.tar.gz - root # cd centreon-esxd-1.X - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/centreon/lib/centreon-esxd - root # cp lib/* /usr/share/centreon/lib/centreon-esxd/ - -Activer le daemon « centreon-esxd » au démarrage:: - - root # chkconfig --level 2345 centreon_esxd on - - -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* - - diff --git a/connectors/vmware/doc/fr/_build/html/_static/ajax-loader.gif b/connectors/vmware/doc/fr/_build/html/_static/ajax-loader.gif deleted file mode 100644 index 61faf8cab23993bd3e1560bff0668bd628642330..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@Cw{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN diff --git a/connectors/vmware/doc/fr/_build/html/_static/basic.css b/connectors/vmware/doc/fr/_build/html/_static/basic.css deleted file mode 100644 index a04c8e137..000000000 --- a/connectors/vmware/doc/fr/_build/html/_static/basic.css +++ /dev/null @@ -1,540 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/_static/comment-bright.png b/connectors/vmware/doc/fr/_build/html/_static/comment-bright.png deleted file mode 100644 index 551517b8c83b76f734ff791f847829a760ad1903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3500 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 A2LJ#7 diff --git a/connectors/vmware/doc/fr/_build/html/_static/comment.png b/connectors/vmware/doc/fr/_build/html/_static/comment.png deleted file mode 100644 index 92feb52b8824c6b0f59b658b1196c61de9162a95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3445 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 Xn!ZpXD%P(H00000NkvXXu0mjf= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('

              ') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); diff --git a/connectors/vmware/doc/fr/_build/html/_static/down-pressed.png b/connectors/vmware/doc/fr/_build/html/_static/down-pressed.png deleted file mode 100644 index 6f7ad782782e4f8e39b0c6e15c7344700cdd2527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}Z23@f-Ava~9&<9T!#}JFtXD=!G zGdl{fK6ro2OGiOl+hKvH6i=D3%%Y^j`yIkRn!8O>@bG)IQR0{Kf+mxNd=_WScA8u_ z3;8(7x2){m9`nt+U(Nab&1G)!{`SPVpDX$w8McLTzAJ39wprG3p4XLq$06M`%}2Yk zRPPsbES*dnYm1wkGL;iioAUB*Or2kz6(-M_r_#Me-`{mj$Z%( diff --git a/connectors/vmware/doc/fr/_build/html/_static/down.png b/connectors/vmware/doc/fr/_build/html/_static/down.png deleted file mode 100644 index 3003a88770de3977d47a2ba69893436a2860f9e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}xaV3tUZ$qnrLa#kt978NlpS`ru z&)HFc^}^>{UOEce+71h5nn>6&w6A!ieNbu1wh)UGh{8~et^#oZ1# z>T7oM=FZ~xXWnTo{qnXm$ZLOlqGswI_m2{XwVK)IJmBjW{J3-B3x@C=M{ShWt#fYS9M?R;8K$~YwlIqwf>VA7q=YKcwf2DS4Zj5inDKXXB1zl=(YO3ST6~rDq)&z z*o>z)=hxrfG-cDBW0G$!?6{M<$@{_4{m1o%Ub!naEtn|@^frU1tDnm{r-UW|!^@B8 diff --git a/connectors/vmware/doc/fr/_build/html/_static/file.png b/connectors/vmware/doc/fr/_build/html/_static/file.png deleted file mode 100644 index d18082e397e7e54f20721af768c4c2983258f1b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP$HyOL$D9)yc9|lc|nKf<9@eUiWd>3GuTC!a5vdfWYEazjncPj5ZQX%+1 zt8B*4=d)!cdDz4wr^#OMYfqGz$1LDFF>|#>*O?AGil(WEs?wLLy{Gj2J_@opDm%`dlax3yA*@*N$G&*ukFv>P8+2CBWO(qz zD0k1@kN>hhb1_6`&wrCswzINE(evt-5C1B^STi2@PmdKI;Vst0PQB6!2kdN diff --git a/connectors/vmware/doc/fr/_build/html/_static/jquery.js b/connectors/vmware/doc/fr/_build/html/_static/jquery.js deleted file mode 100644 index 198b3ff07..000000000 --- a/connectors/vmware/doc/fr/_build/html/_static/jquery.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.1 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
              a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
              "+""+"
              ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
              t
              ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
              ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

              ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
              ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
              ","
              "],thead:[1,"","
              "],tr:[2,"","
              "],td:[3,"","
              "],col:[2,"","
              "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
              ","
              "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
              ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/_static/minus.png b/connectors/vmware/doc/fr/_build/html/_static/minus.png deleted file mode 100644 index da1c5620d10c047525a467a425abe9ff5269cfc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknK< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF diff --git a/connectors/vmware/doc/fr/_build/html/_static/pygments.css b/connectors/vmware/doc/fr/_build/html/_static/pygments.css deleted file mode 100644 index d79caa151..000000000 --- a/connectors/vmware/doc/fr/_build/html/_static/pygments.css +++ /dev/null @@ -1,62 +0,0 @@ -.highlight .hll { background-color: #ffffcc } -.highlight { background: #eeffcc; } -.highlight .c { color: #408090; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ -.highlight .k { color: #007020; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ -.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #007020 } /* Comment.Preproc */ -.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ -.highlight .gd { color: #A00000 } /* Generic.Deleted */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #333333 } /* Generic.Output */ -.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ -.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #007020 } /* Keyword.Pseudo */ -.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #902000 } /* Keyword.Type */ -.highlight .m { color: #208050 } /* Literal.Number */ -.highlight .s { color: #4070a0 } /* Literal.String */ -.highlight .na { color: #4070a0 } /* Name.Attribute */ -.highlight .nb { color: #007020 } /* Name.Builtin */ -.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ -.highlight .no { color: #60add5 } /* Name.Constant */ -.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ -.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #007020 } /* Name.Exception */ -.highlight .nf { color: #06287e } /* Name.Function */ -.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ -.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ -.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #bb60d5 } /* Name.Variable */ -.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #208050 } /* Literal.Number.Float */ -.highlight .mh { color: #208050 } /* Literal.Number.Hex */ -.highlight .mi { color: #208050 } /* Literal.Number.Integer */ -.highlight .mo { color: #208050 } /* Literal.Number.Oct */ -.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ -.highlight .sc { color: #4070a0 } /* Literal.String.Char */ -.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ -.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ -.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ -.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ -.highlight .sx { color: #c65d09 } /* Literal.String.Other */ -.highlight .sr { color: #235388 } /* Literal.String.Regex */ -.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ -.highlight .ss { color: #517918 } /* Literal.String.Symbol */ -.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ -.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ -.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ -.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/_static/searchtools.js b/connectors/vmware/doc/fr/_build/html/_static/searchtools.js deleted file mode 100644 index 56676b25b..000000000 --- a/connectors/vmware/doc/fr/_build/html/_static/searchtools.js +++ /dev/null @@ -1,622 +0,0 @@ -/* - * searchtools.js_t - * ~~~~~~~~~~~~~~~~ - * - * Sphinx JavaScript utilties for the full-text search. - * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - - -/** - * Porter Stemmer - */ -var Stemmer = function() { - - var step2list = { - ational: 'ate', - tional: 'tion', - enci: 'ence', - anci: 'ance', - izer: 'ize', - bli: 'ble', - alli: 'al', - entli: 'ent', - eli: 'e', - ousli: 'ous', - ization: 'ize', - ation: 'ate', - ator: 'ate', - alism: 'al', - iveness: 'ive', - fulness: 'ful', - ousness: 'ous', - aliti: 'al', - iviti: 'ive', - biliti: 'ble', - logi: 'log' - }; - - var step3list = { - icate: 'ic', - ative: '', - alize: 'al', - iciti: 'ic', - ical: 'ic', - ful: '', - ness: '' - }; - - var c = "[^aeiou]"; // consonant - var v = "[aeiouy]"; // vowel - var C = c + "[^aeiouy]*"; // consonant sequence - var V = v + "[aeiou]*"; // vowel sequence - - var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 - var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 - var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 - var s_v = "^(" + C + ")?" + v; // vowel in stem - - this.stemWord = function (w) { - var stem; - var suffix; - var firstch; - var origword = w; - - if (w.length < 3) - return w; - - var re; - var re2; - var re3; - var re4; - - firstch = w.substr(0,1); - if (firstch == "y") - w = firstch.toUpperCase() + w.substr(1); - - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) - w = w.replace(re,"$1$2"); - else if (re2.test(w)) - w = w.replace(re2,"$1$2"); - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); - } - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) - w = w + "e"; - else if (re3.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - else if (re4.test(w)) - w = w + "e"; - } - } - - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) - w = stem + "i"; - } - - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step2list[suffix]; - } - - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step3list[suffix]; - } - - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) - w = stem; - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) - w = stem; - } - - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) - w = stem; - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - - // and turn initial Y back to y - if (firstch == "y") - w = firstch.toLowerCase() + w.substr(1); - return w; - } -} - - - -/** - * Simple result scoring code. - */ -var Scorer = { - // Implement the following function to further tweak the score for each result - // The function takes a result array [filename, title, anchor, descr, score] - // and returns the new score. - /* - score: function(result) { - return result[4]; - }, - */ - - // query matches the full name of an object - objNameMatch: 11, - // or matches in the last dotted part of the object name - objPartialMatch: 6, - // Additive scores depending on the priority of the object - objPrio: {0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5}, // used to be unimportantResults - // Used when the priority is not in the mapping. - objPrioDefault: 0, - - // query found in title - title: 15, - // query found in terms - term: 5 -}; - - -/** - * Search Module - */ -var Search = { - - _index : null, - _queued_query : null, - _pulse_status : -1, - - init : function() { - var params = $.getQueryParameters(); - if (params.q) { - var query = params.q[0]; - $('input[name="q"]')[0].value = query; - this.performSearch(query); - } - }, - - loadIndex : function(url) { - $.ajax({type: "GET", url: url, data: null, - dataType: "script", cache: true, - complete: function(jqxhr, textstatus) { - if (textstatus != "success") { - document.getElementById("searchindexloader").src = url; - } - }}); - }, - - setIndex : function(index) { - var q; - this._index = index; - if ((q = this._queued_query) !== null) { - this._queued_query = null; - Search.query(q); - } - }, - - hasIndex : function() { - return this._index !== null; - }, - - deferQuery : function(query) { - this._queued_query = query; - }, - - stopPulse : function() { - this._pulse_status = 0; - }, - - startPulse : function() { - if (this._pulse_status >= 0) - return; - function pulse() { - var i; - Search._pulse_status = (Search._pulse_status + 1) % 4; - var dotString = ''; - for (i = 0; i < Search._pulse_status; i++) - dotString += '.'; - Search.dots.text(dotString); - if (Search._pulse_status > -1) - window.setTimeout(pulse, 500); - } - pulse(); - }, - - /** - * perform a search for something (or wait until index is loaded) - */ - performSearch : function(query) { - // create the required interface elements - this.out = $('#search-results'); - this.title = $('

              ' + _('Searching') + '

              ').appendTo(this.out); - this.dots = $('').appendTo(this.title); - this.status = $('

              ').appendTo(this.out); - this.output = $('
              '); - } - // Prettify the comment rating. - comment.pretty_rating = comment.rating + ' point' + - (comment.rating == 1 ? '' : 's'); - // Make a class (for displaying not yet moderated comments differently) - comment.css_class = comment.displayed ? '' : ' moderate'; - // Create a div for this comment. - var context = $.extend({}, opts, comment); - var div = $(renderTemplate(commentTemplate, context)); - - // If the user has voted on this comment, highlight the correct arrow. - if (comment.vote) { - var direction = (comment.vote == 1) ? 'u' : 'd'; - div.find('#' + direction + 'v' + comment.id).hide(); - div.find('#' + direction + 'u' + comment.id).show(); - } - - if (opts.moderator || comment.text != '[deleted]') { - div.find('a.reply').show(); - if (comment.proposal_diff) - div.find('#sp' + comment.id).show(); - if (opts.moderator && !comment.displayed) - div.find('#cm' + comment.id).show(); - if (opts.moderator || (opts.username == comment.username)) - div.find('#dc' + comment.id).show(); - } - return div; - } - - /** - * A simple template renderer. Placeholders such as <%id%> are replaced - * by context['id'] with items being escaped. Placeholders such as <#id#> - * are not escaped. - */ - function renderTemplate(template, context) { - var esc = $(document.createElement('div')); - - function handle(ph, escape) { - var cur = context; - $.each(ph.split('.'), function() { - cur = cur[this]; - }); - return escape ? esc.text(cur || "").html() : cur; - } - - return template.replace(/<([%#])([\w\.]*)\1>/g, function() { - return handle(arguments[2], arguments[1] == '%' ? true : false); - }); - } - - /** Flash an error message briefly. */ - function showError(message) { - $(document.createElement('div')).attr({'class': 'popup-error'}) - .append($(document.createElement('div')) - .attr({'class': 'error-message'}).text(message)) - .appendTo('body') - .fadeIn("slow") - .delay(2000) - .fadeOut("slow"); - } - - /** Add a link the user uses to open the comments popup. */ - $.fn.comment = function() { - return this.each(function() { - var id = $(this).attr('id').substring(1); - var count = COMMENT_METADATA[id]; - var title = count + ' comment' + (count == 1 ? '' : 's'); - var image = count > 0 ? opts.commentBrightImage : opts.commentImage; - var addcls = count == 0 ? ' nocomment' : ''; - $(this) - .append( - $(document.createElement('a')).attr({ - href: '#', - 'class': 'sphinx-comment-open' + addcls, - id: 'ao' + id - }) - .append($(document.createElement('img')).attr({ - src: image, - alt: 'comment', - title: title - })) - .click(function(event) { - event.preventDefault(); - show($(this).attr('id').substring(2)); - }) - ) - .append( - $(document.createElement('a')).attr({ - href: '#', - 'class': 'sphinx-comment-close hidden', - id: 'ah' + id - }) - .append($(document.createElement('img')).attr({ - src: opts.closeCommentImage, - alt: 'close', - title: 'close' - })) - .click(function(event) { - event.preventDefault(); - hide($(this).attr('id').substring(2)); - }) - ); - }); - }; - - var opts = { - processVoteURL: '/_process_vote', - addCommentURL: '/_add_comment', - getCommentsURL: '/_get_comments', - acceptCommentURL: '/_accept_comment', - deleteCommentURL: '/_delete_comment', - commentImage: '/static/_static/comment.png', - closeCommentImage: '/static/_static/comment-close.png', - loadingImage: '/static/_static/ajax-loader.gif', - commentBrightImage: '/static/_static/comment-bright.png', - upArrow: '/static/_static/up.png', - downArrow: '/static/_static/down.png', - upArrowPressed: '/static/_static/up-pressed.png', - downArrowPressed: '/static/_static/down-pressed.png', - voting: false, - moderator: false - }; - - if (typeof COMMENT_OPTIONS != "undefined") { - opts = jQuery.extend(opts, COMMENT_OPTIONS); - } - - var popupTemplate = '\ -
              \ -

              \ - Sort by:\ - best rated\ - newest\ - oldest\ -

              \ -
              Comments
              \ -
              \ - loading comments...
              \ -
                \ -
                \ -

                Add a comment\ - (markup):

                \ -
                \ - reStructured text markup: *emph*, **strong**, \ - ``code``, \ - code blocks: :: and an indented block after blank line
                \ -
                \ - \ -

                \ - \ - Propose a change ▹\ - \ - \ - Propose a change ▿\ - \ -

                \ - \ - \ - \ - \ - \ -
                \ -
                '; - - var commentTemplate = '\ -
                \ -
                \ -
                \ - \ - \ - \ - \ - \ - \ -
                \ -
                \ - \ - \ - \ - \ - \ - \ -
                \ -
                \ -
                \ -

                \ - <%username%>\ - <%pretty_rating%>\ - <%time.delta%>\ -

                \ -
                <#text#>
                \ -

                \ - \ - reply ▿\ - proposal ▹\ - proposal ▿\ - \ - \ -

                \ -
                \
                -<#proposal_diff#>\
                -        
                \ -
                  \ -
                  \ -
                  \ -
                  \ - '; - - var replyTemplate = '\ -
                • \ -
                  \ -
                  \ - \ - \ - \ - \ - \ - \ -
                  \ -
                • '; - - $(document).ready(function() { - init(); - }); -})(jQuery); - -$(document).ready(function() { - // add comment anchors for all paragraphs that are commentable - $('.sphinx-has-comment').comment(); - - // highlight search words in search results - $("div.context").each(function() { - var params = $.getQueryParameters(); - var terms = (params.q) ? params.q[0].split(/\s+/) : []; - var result = $(this); - $.each(terms, function() { - result.highlightText(this.toLowerCase(), 'highlighted'); - }); - }); - - // directly open comment window if requested - var anchor = document.location.hash; - if (anchor.substring(0, 9) == '#comment-') { - $('#ao' + anchor.substring(9)).click(); - document.location.hash = '#s' + anchor.substring(9); - } -}); diff --git a/connectors/vmware/doc/fr/_build/html/exploitation/index.html b/connectors/vmware/doc/fr/_build/html/exploitation/index.html deleted file mode 100644 index 8982a0e59..000000000 --- a/connectors/vmware/doc/fr/_build/html/exploitation/index.html +++ /dev/null @@ -1,2376 +0,0 @@ - - - - - - - - Exploitation — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - -
                  -
                  -
                  -
                  - -
                  -

                  Exploitation¶

                  -
                  -

                  Présentation de Centreon-esxd¶

                  -
                  -

                  Principes Généraux¶

                  -

                  Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d’un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter.

                  -

                  Par défaut, « centreon-esxd Â» lance au moins deux processus (nommé respectivement « handle-client Â», « handle-vsphere-xxxx Â») :

                  -
                  -
                  « handle-client Â»:
                  -
                  Processus en attente des demandes des clients « centreon_esx_client.pl Â».
                  -
                  -

                  Voici le fonctionnement :

                  -
                    -
                  • Un client se connecte.
                  • -
                  • Le client demande un indicateur de supervision sur un VirtualCenter.
                  • -
                  • Le processus « handle-client Â» fourni cette demande au processus « handle-vsphere-xxxx Â».
                  • -
                  • Une réponse est fournie par « handle-vsphere-xxxx Â» à « handle-client Â».
                  • -
                  • Le processus « handle-client Â» fourni la réponse au client.
                  • -
                  -
                  -
                  « handle-vsphere-xxxx Â»:
                  -
                  Processus ayant le rôle de se connecter et garder ouverte une session avec son VirtualCenter (De plus, dans un souci de performances, un cache de description des données de performances est créé).
                  -
                  -

                  Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande.

                  -

                  Centreon-esxd nécessite impérativement l’utilisation d’un (ou plusieurs) VirtualCenter. Il n’est pas possible de récupérer les informations d’un serveur ESX directement.

                  -

                  Voici un exemple d’architecture éclaté :

                  -../_images/archi.png -
                  -
                  -

                  Mode de fonctionnement¶

                  -

                  Le programme « centreon-esxd Â» fonctionne uniquement en mode « daemon Â». (dans le sens où il ne peut fournir les indicateurs sans l’utilisation d’un client).

                  -

                  Lors de l’utilisation du plugin centreon_esx_client.pl, on passe des chaînes de caractères qui vont être lier aux différentes librairies dans “/usr/share/centreon/lib/centreon-esxd” et qui va être ensuite communiquer au Vcenter qui va au final retourner le résultat au Client. Le client ouvre une liaison TCP avec le serveur pour récolter les informations nécessaires.

                  -
                  -
                  -

                  Configuration du connecteur¶

                  -

                  Le daemon « centreon-esxd Â» possède un fichier de configuration « centreon_esxd.pm Â» de la forme suivante :

                  -
                  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',
                  -                                   'password' => 'XXXXXX'}
                  -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";
                  -
                  -

                  La variable «%vsphere_server Â» permet de configurer les accès aux différents VirtualCenter. Il est nécessaire d’avoir au moins l’entrée ‘default’.

                  -

                  La variable « $port Â» permet de configurer le port d’écoute du connecteur « centreon-esxd Â».

                  -

                  Il est aussi possible de modifier la variable « $log_mode Â» si vous souhaitez utiliser « syslog Â» au lieu d’un fichier à plat.

                  -

                  Il est déconseillé de modifier les variables suivantes : « $REFRESH_KEEPER_SESSION Â», « $TIMEOUT_KILL Â», « $ TIMEOUT_VSPHERE Â» et « $TIMEOUT Â», car ils sont configurés pour une utilisation optimale.

                  -
                  -
                  -
                  -

                  Optimisation de la configuration dans Centreon¶

                  -

                  Afin d’exploiter pleinement « centreon-esxd Â», il est recommandé d’effectuer une série d’action préalablement.

                  -

                  Ce connecteur permet la définition de trois modèles d’hôtes :

                  -
                    -
                  • le modèle hôte « VMWare-VM Â» : modèle d’une machine virtuelle.
                  • -
                  • le modèle hôte « VMWare-ESX Â» : modèle d’un serveur ESX.
                  • -
                  • le modèle hôte « VMWare-VC Â» : modèle d’un virtualCenter (Ce modèle contient notamment des services pour les « datastores Â»)
                  • -
                  -

                  Tous les plugins de contrôle VMWare ont quelques attributs en commun, qui peuvent être défini dans des modèles afin de simplifier la configuration.

                  -
                  ----- - - - - - - - - - - - - - - - - - - - - -
                  Macro NameMacro ValueRessource ou la macro doit être défini (recommandé)
                  HOSTESXDHOSTIp ou nom d’hôte du serveur exécutant le daemon « centreon-esxd Â»Modèle d’hôte VMWare-* de plus bas niveau
                  HOSTESXDPORTPort du daemonModèle d’hôte VMWare-* de plus bas niveau
                  HOSTVCNAMENom identifiant le VirtualCenterModèle d’hôte VMWare-* de plus bas niveau
                  -

                  Le login et le mot de passe du VirtualCenter se situe directement dans le fichier de configuration « centreon_esxd.pm Â» qui se situe normalement dans “/etc/centreon/centreon_esxd.pm” . Ce système évite la visualisation d’un mot de passe dans l’interface « centreon Â».

                  -
                  -

                  Création d’un modèle d’hôte VMWare générique¶

                  -

                  Aller dans le menu configuration/host/template/, et créer un modèle d’hôte « VMWare Â». Ce modèle d’hôte sera le modèle parent pour les modèles « VMWare-VM Â», « VMWare-ESX Â» et « VMWare-VC Â».

                  -

                  Configurer l’ensemble des champs comme indiqué dans la documentation Centreon.

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  ESXDHOSTExemple: 10.30.10.30
                  ESXDPORT5700 (port par défaut)
                  VCNAMEdefault
                  -
                  -
                  -

                  Troubleshooting¶

                  -

                  Il est possible de retrouver des erreurs de ce type dans les « log Â» de « centreon-esxd Â» :

                  -
                  ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac...
                  -
                  -
                  -

                  Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur.

                  -

                  Il est nécessaire de remonter un problème dans le cas d’un trop grand nombres de déconnexion du daemon au VirtualCenter.

                  -
                  -
                  -
                  -

                  Liste des contrôles¶

                  -
                  -

                  Contrôles ESX¶

                  -
                  -

                  CPU¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_cpuhost
                  DescriptionContrôle le taux d’utilisation CPU d’un serveur ESX. Le nombre de métrique renvoyé dépend du nombre de CPUs.
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéescpu_total=17.87%;10;90;0;100 cpu0=10.38%;;0;100 cpu1=8.66%;;0;100 cpu2=9.45%;;0;100 cpu3=8.91%;;0;100
                  Interval/Retry(min)5/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlercpuhost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
                  --light-perfdata(optionnel) Permet d’afficher uniquement la perfdata du CPU total 
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING80
                  CRITICAL90
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u cpuhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  MEMOIRE¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_memhost
                  Description
                  -
                  Contrôle le taux d’utilisation mémoire d’un serveur ESX. 3 métriques sont renvoyés :
                  -
                    -
                  • le taux d’utilisation mémoire (en octets),
                  • -
                  • la taille totale de la mémoire (en octets),
                  • -
                  • la mémoire suralloué par la totalité des VMs (‘overhead’ en octets)
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéesused=56196403200o;6870586573;61835279155;0;68705865728 size=68705865728o overhead=1773761536o
                  Interval/Retry(min)20/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlermemhost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING80
                  CRITICAL90
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u memhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  RESEAU¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_nethost
                  Description
                  -
                  Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés :
                  -
                    -
                  • le taux d’utilisation en entrée et sortie (en b/s).
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la(les) métrique(s) « traffic_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la(les) métrique(s) « traffic_* Â» est(sont) au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéestraffic_in=598016b/s traffic_out=172032b/s
                  Interval/Retry(min)5/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlernethost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  --nicNom de l’interface réseau physiquevmnic0
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  NICNAME 
                  WARNING80
                  CRITICAL90
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u nethost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$ --nic "$_SERVICENICNAME$"
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  SWAP¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_swaphost
                  Description
                  -
                  Contrôle le taux d’utilisation mémoire d’un serveur ESX. 2 métriques sont renvoyés :
                  -
                    -
                  • le taux de lecture et d’écriture du swap globale de l’ensemble des machines virtuelles (en Mb/s).
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la(les) métrique(s) « swap_* Â» est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la(les) métrique(s) « swap_* Â» est(sont) au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéesswap_in=0b/s swap_out=0b/s
                  Interval/Retry(min)20/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerswaphost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -w ou --warning(optionnel – Défaut : 0.8) Seuil warning en MB/s0.5
                  -c ou --critical(optionnel – Défaut : 1) Seuil critique en MB/s1.5
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING0.8
                  CRITICAL1
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u swaphost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  DATASTORES¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_datastoreshost
                  Description
                  -
                  Contrôle le taux d’utilisation d’une interface réseau physique d’un serveur ESX. 2 métriques sont renvoyés par le datastore :
                  -
                    -
                  • la latence totale en lecture et écriture (en ms).
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la(les) métrique(s) est(sont) en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la(les) métrique(s) est(sont) en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la(les) métrique(s) est(sont) au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyées‘trl_LUN1’=0.00ms ‘twl_LUN1’=0.00ms ‘trl_LUN2’=0.00ms ‘twl_LUN2’=1.00ms
                  Interval/Retry(min)5/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerdatastoreshost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  --filter-datastores(optionnel) Permet de filtrer les datastores à traiter (séparé par des virgules)LUN1,LUN2
                  -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms75
                  -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms90
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING30
                  CRITICAL50
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u datastoreshost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  COUNTVM¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_countvmhost
                  Description
                  -
                  Contrôle le taux d’utilisation mémoire d’un serveur ESX. 1 métrique est remontée :
                  -
                    -
                  • le nombre de machines virtuelles allumées.
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « count Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « count Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « count Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéescount=45
                  Interval/Retry(min)20/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlercountvmhost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -w ou --warning(optionnel – Défaut : aucunes valeurs) Seuil warning en ms10
                  -c ou --critical(optionnel – Défaut : aucunes valeurs) Seuil critique en ms15
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING10
                  CRITICAL15
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u countvmhost --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  HEALTH¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_healthhost
                  DescriptionContrôle l’état des sondes matériels et processeurs d’un serveur ESX.
                  Fonctionnement
                  -
                  Remonte un état selon l’état des sondes:
                  -
                    -
                  • “Yellow” correspond à WARNING.
                  • -
                  • “Red” correspond à CRITICAL.
                  • -
                  -
                  -
                  -
                  Métriques renvoyées 
                  Interval/Retry(min)30/1
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerhealthhost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                    
                    
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u healthhost
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  MAINTENANCE¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_maintenancehost
                  DescriptionContrôle le mode de maintenance d’un serveur ESX.
                  Fonctionnement
                    -
                  • Remonte l’état « CRITICAL » si le serveur ESX est en mode de maintenance.
                  • -
                  -
                  Métriques renvoyées 
                  Interval/Retry(min)30/1
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlermaintenancehost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                    
                    
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u maintenancehost
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  STATUT¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_statushost
                  DescriptionContrôle l’état global d’un serveur ESX.
                  Fonctionnement
                    -
                  • Remonte l’état « CRITICAL » si le statut du serveur ESX est en « red » .
                  • -
                  • Remonte l’état « WARNING » si le statut du serveur ESX est en « yellow » .
                  • -
                  • Remonte l’état « UNKNOWN » si le statut du serveur ESX est en « gray » .
                  • -
                  -
                  Métriques renvoyées 
                  Interval/Retry(min)30/1
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerstatushost
                  -e ou --esx-hostNom du serveur ESX cibléesx1.test.fr
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                    
                    
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" -e "$HOSTADDRESS$" -u statushost
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -
                  -

                  Contrôles d’une machine virtuelle¶

                  -
                  -

                  CPU¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_cpuvm
                  DescriptionContrôle le taux d’utilisation CPU d’une machine virtuelle. Le nombre de métrique renvoyé dépend du nombre de CPUs.
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « cpu_total Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « cpu_total Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « cpu_total Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéescpu_total=0.22%;80;90;0;100 cpu_total_MHz=5.00MHz cpu0_MHz=2.00MHz
                  Interval/Retry(min)5/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlercpuvm
                  --vmNom de la machine virtuelle cibléemyvmname
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING80
                  CRITICAL90
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u cpuvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  MEMOIRE¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_memvm
                  Description
                  -
                  Contrôle le taux d’utilisation mémoire d’une machine virtuelle. 6 métriques sont renvoyés :
                  -
                    -
                  • « used Â» : la taille mémoire occupée par la machine virtuelle sur le serveur physique (en octets)
                  • -
                  • « size Â» : la taille totale de la mémoire allouée pour la machine virtuelle (en octets)
                  • -
                  • « overhead Â» : la mémoire sur-alloué (en octets)
                  • -
                  • « ballooning Â», « shared Â» et « active Â».
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéesusage=362747904o;1717986918;1932735283;0;2147483648 size=2147483648o overhead=22743040o ballooning=0o shared=4561920o active=70148096o
                  Interval/Retry(min)20/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlermemvm
                  --vmNom de la machine virtuelle cibléemyvmname
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING80
                  CRITICAL90
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u memvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  DATASTORES¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_datastoresvm
                  Description
                  -
                  Contrôle le taux d’utilisation des datastores rattachées à une machine virtuelle. 2 métriques sont renvoyés par datastore :
                  -
                    -
                  • « riops Â» : le nombre moyen d’I/O de lectures par seconde
                  • -
                  • « wiops Â» : le nombre moyen d’I/O d’écritures par seconde
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si une métrique est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si une métrique est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si une métrique est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyées‘riops_LUN1’=0.00iops ‘wiops_LUN1’=0.27iops ‘riops_LUN2’=20.00iops ‘wiops_LUN2’=100.2iops
                  Interval/Retry(min)5/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerdatastoresvm
                  --vmNom de la machine virtuelle cibléemyvmname
                  -w ou --warning(optionnel – Défaut : aucunes) Seuil warning en ms100
                  -c ou --critical(optionnel – Défaut : aucunes) Seuil critique en ms150
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  WARNING100
                  CRITICAL150
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u datastoresvm --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  VMTOOLS¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_toolsvm
                  DescriptionContrôle l’état des VMTools rattachées à une machine virtuelle.
                  Fonctionnement
                    -
                  • Remonte l’état « WARNING » si les VMTools sont ‘toolsold’.
                  • -
                  • Remonte l’état « CRITICAL » si les VMTools sont ‘toolsnotrunning’ ou ‘toolsnotinstalled’.
                  • -
                  -
                  Métriques renvoyées 
                  Interval/Retry(min)20/1
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlertoolsvm
                  --vmNom de la machine virtuelle cibléemyvmname
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                    
                    
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u toolsvm
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  SNAPSHOTS¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_snapshotvm
                  DescriptionContrôle la présence et/ou la date de création des snapshots rattachées à une machine virtuelle.
                  Fonctionnement
                  -
                  L’état dépend des paramètres du plugin :
                  -
                    -
                  • Si « –warn Â» spécifié seul : remonte un état WARNING si un snapshost est présent.
                  • -
                  • Si « –crit Â» spécifié seul : remonte un état CRITICAL si un snapshost est présent.
                  • -
                  • Si « –warn Â» et « –older XXX Â» : remonte un état WARNING si un snapshost est présent et la date de création du -snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
                  • -
                  • Si « –crit Â» et « –older XXX Â» : remonte un état CRITICAL si un snapshost est présent et la date de création du -snapshot le plus ancien est plus vielle que « temps_courant – XXX Â»
                  • -
                  -
                  -
                  -
                  Métriques renvoyées 
                  Interval/Retry(min)20/1
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlersnapshotvm
                  --vmNom de la machine virtuelle cibléemyvmname
                  --warn(optionnel) Permet de spécifier un état WARNING 
                  --crit(optionnel) Permet de spécifier un état CRITICAL 
                  --older(optionnel) le temps en secondes du snaphost le plus vieux par rapport au temps courant86400 (snapshot vieux de + 1jour)
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  THRESHOLD
                    -
                  • -warn
                  • -
                  -
                    
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --vm "$HOSTADDRESS$" -u snapshotvm $_SERVICETHRESHOLD$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -
                  -

                  Contrôle d’un datastore¶

                  -
                  -

                  USAGE¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_datastoreusage
                  Description
                  -
                  Contrôle le taux d’utilisation d’un datastore. 2 métriques sont renvoyés :
                  -
                    -
                  • « used Â» : l’espace occupé par le datastore (en octets)
                  • -
                  • « size Â» : la taille totale allouée pour le datastore (en octets)
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéesused=506574405632o;;;0;643976658944 size=643976658944o
                  Interval/Retry(min)20/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerdatastore-usage
                  -e ou --esx-hostNom du datastore ciblédsname
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en pourcentage75
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en pourcentage90
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  DSNAME 
                  WARNING80
                  CRITICAL90
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-usage --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -

                  DATASTORE I/O¶

                  -
                  -
                  Fiche d’identité¶
                  - ---- - - - - - - - - - - - - - - - - - -
                  Nom du plugincheck_merethis_vmware_datastorio
                  Description
                  -
                  Contrôle le taux d’utilisation (I/O) d’un datastore. 2 métriques sont renvoyés :
                  -
                    -
                  • « read_rate Â» : le taux d’utilisation moyen en lecture par seconde (en b/s)
                  • -
                  • « write_rate Â» : la taille d’utilisation moyen en écriture par seconde (en b/s)
                  • -
                  -
                  -
                  -
                  Fonctionnement
                    -
                  • Remonte un état OK si la métrique « used Â» est en dessous du seuil WARNING.
                  • -
                  • Remonte un état WARNING si la métrique « used Â» est en dessous du seuil CRITICAL et au dessus du seuil WARNING.
                  • -
                  • Remonte un état CRITICAL si la métrique « used Â» est au dessus du seuil CRITICAL.
                  • -
                  -
                  Métriques renvoyéesread_rate=1589248b/s write_rate=14344192b/s
                  Interval/Retry(min)5/5
                  -
                  -
                  -
                  Attribut du contrôle¶
                  - ----- - - - - - - - - - - - - - - - - - - - - - - - - -
                  AttributDescriptionExemple
                  -uIndicateur à contrôlerdatastore-io
                  -e ou --esx-hostNom du datastore ciblédsname
                  -w ou --warning(optionnel – Défaut : 80) Seuil warning en kBps100
                  -c ou --critical(optionnel – Défaut : 90) Seuil critique en kBps200
                  -

                  Le plugin a également besoin des informations sur le daemon « centreon-esxd Â».

                  - ---- - - - - - - - - - - - - - -
                  OptionComportement
                  -HIP ou adresse du serveur hébergeant « centreon-esxd Â»
                  -P(optionnel – Défaut : 5700) Port du serveur hébergeant « centreon-esxd Â»
                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  -
                  -
                  -
                  Création d’un service et/ou modèle de service¶
                  -

                  Aller dans le menu configuration/service ou template, et créer un service et ou modèle de service (basé sur le modèle de service générique).

                  -

                  Définir les macros suivante :

                  - ---- - - - - - - - - - - - - - - - - -
                  Macro NameMacro Value
                  DSNAME 
                  WARNING100
                  CRITICAL150
                  -
                  -
                  -
                  Création d’une check command¶
                  -

                  Afin de simplifier l’utilisation de ce contrôle, il est recommandé de créer la check command suivante :

                  -
                  $USER1$/centreon_esx_client.pl -H "$_HOSTESXDHOST$" -P "$_HOSTESXDPORT$" --vsphere "$_HOSTVCNAME$" --datastore "$_SERVICEDSNAME$" -u datastore-io --warning $_SERVICEWARNING$ --critical $_SERVICECRITICAL$
                  -
                  -

                  L’ensemble des attributs sont déjà défini dans le modèle d’hôte et/ou hôte, et modèle de service et/ou service.

                  -
                  -
                  -
                  -
                  -
                  - - - - - -
                  -
                  -

                  Table Of Contents

                  - - -

                  Previous topic

                  -

                  Installation

                  -

                  This Page

                  - - - -
                  -
                  -
                  - - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/genindex.html b/connectors/vmware/doc/fr/_build/html/genindex.html deleted file mode 100644 index 461f46511..000000000 --- a/connectors/vmware/doc/fr/_build/html/genindex.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - Index — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - -
                  -
                  -
                  -
                  - - -

                  Index

                  - -
                  - -
                  - - -
                  -
                  -
                  -
                  -
                  - - - - - -
                  -
                  -
                  -
                  - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/index.html b/connectors/vmware/doc/fr/_build/html/index.html deleted file mode 100644 index 7bce10796..000000000 --- a/connectors/vmware/doc/fr/_build/html/index.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - Welcome to Centreon ESXD’s documentation! — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - -
                  - -
                  -
                  -

                  Table Of Contents

                  - - -

                  Next topic

                  -

                  Installation

                  -

                  This Page

                  - - - -
                  -
                  -
                  -
                  - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/installation/index.html b/connectors/vmware/doc/fr/_build/html/installation/index.html deleted file mode 100644 index 9b05d179c..000000000 --- a/connectors/vmware/doc/fr/_build/html/installation/index.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - - - - - Installation — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - - -
                  -
                  -
                  -
                  - -
                  -

                  Installation¶

                  -
                  -

                  Pré-Requis¶

                  -
                  -

                  Préconisations logicielles¶

                  -

                  Le connecteur “centreon-esxd” est testé et validé sur des environnements Linux. -L’installation sur d’autres environnements n’est pas exclu mais non présenté dans ce document (Solaris, Windows, ...).

                  - ---- - - - - - - - - - - - - - - - - -
                  LogicielsVersion minimum
                  VMWare SDK Perl5.0
                  Perl5.8
                  centreon-esxd1.3
                  -
                  -
                  -

                  Préconisations matérielles¶

                  -

                  Le matériel nécessaire dépend du nombre de demandes de vérifications. Par défaut, le connecteur n’effectue aucunes vérifications. Les ressources minimales sont de :

                  -
                    -
                  • mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle).
                  • -
                  • CPU : même pré-requis que pour le serveur de collecte.
                  • -
                  -
                  -
                  -
                  -

                  Installation de centreon-esxd - Environnement centos/rhel 5¶

                  -
                  -

                  Installation du SDK Perl VMWare¶

                  -

                  Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l’installer. Pour cela nous allons commencer par installer CPAN qui est le nom d’un module Perl qui rend aisés le téléchargement, l’installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN.

                  -

                  Installer les pré-requis CPAN:

                  -
                  root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel
                  -root # yum install perl-XML-LibXML perl-Crypt-SSLeay
                  -
                  -root # cpan install Class::MethodMaker
                  -root # cpan install LWP
                  -root # cpan install Net::SSLeay
                  -root # cpan install LWP::Protocol::https
                  -root # cpan install SOAP::Lite
                  -
                  -root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
                  -root # tar zxvf UUID-0.04.tar.gz
                  -root # cd UUID-0.04
                  -root # perl Makefile.PL
                  -root # make && make install
                  -
                  -
                  -

                  Nous avons notre environnement prêt pour l’installation du SDK VMWare.

                  -

                  Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (SDK VMWare).

                  -

                  Installer le SDK Perl VMWare:

                  -
                  root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
                  -root # cd vmware-vsphere-cli-distrib
                  -root # perl Makefile.pl
                  -root # make && make install
                  -
                  -
                  -
                  -
                  -

                  Installation de modules complémentaires¶

                  -

                  Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd :

                  -

                  Pour envoyer les logs au daemon « syslog Â», il est nécessaire d’installer le module « Unix::Syslog »:

                  -
                  root # cpan install Unix::Syslog
                  -
                  -
                  -

                  Pour vérifier la date des snapshots d’une machine virtuelle, il est nécessaire d’installer le module « DateTime::Format::ISO8601 Â» ( ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl Â». Cette mise à jour est très risqué ):

                  -
                  root # cpan install DateTime
                  -root # cpan install DateTime::Format::ISO8601
                  -root # o conf make /usr/bin/make
                  -root # o conf commit
                  -
                  -
                  -

                  Ensuite redémarrer votre système.

                  -
                  -
                  -

                  Installation de centreon-esxd¶

                  -

                  Télécharger l’archive de « centreon-esxd Â».

                  -

                  Installer les fichiers:

                  -
                  root # tar zxvf centreon-esxd-1.X.tar.gz
                  -root # cd centreon-esxd-1.X
                  -root # cp centreon_esxd /usr/bin/
                  -
                  -root # mkdir -p /etc/centreon
                  -root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
                  -root # cp centreon_esxd-init /etc/init.d/centreon_esxd
                  -
                  -root # mkdir -p /usr/share/centreon/lib/centreon-esxd
                  -root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
                  -
                  -
                  -

                  Activer le daemon « centreon-esxd Â» au démarrage:

                  -
                  root # chkconfig --level 2345 centreon_esxd on
                  -
                  -
                  -

                  Le plugin « nagios Â» correspond au fichier « centreon_esx_client.pl Â».

                  -
                  -
                  -
                  -

                  Installation de centreon-esxd - Environnement centos/rhel 6¶

                  -
                  -

                  Installation du sdk Perl VMWare¶

                  -

                  Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement.

                  -

                  Le connecteur « centreon-esxd Â» utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l’installer. Pour cela nous allons commencer par installer CPAN qui est le nom d’un module Perl qui rend aisés le téléchargement, l’installation, la mise à jour et la maintenance des autres modules Perl qui sont archivés sur le CPAN.

                  -

                  Installer les pré-requis CPAN:

                  -
                  root # yum install gcc make unzip wget expat-devel e2fsprogs-devel openssl-devel perl-CPAN libuuid-devel
                  -root # yum install perl-XML-LibXML perl-Crypt-SSLeay perl-Class-MethodMaker perl-SOAP-Lite
                  -
                  -root # cpan install Test::More
                  -root # cpan install LWP
                  -root # cpan install Net::SSLeay
                  -root # cpan install LWP::Protocol::https
                  -
                  -root # wget http://search.cpan.org/CPAN/authors/id/J/JN/JNH/UUID-0.04.tar.gz
                  -root # tar zxvf UUID-0.04.tar.gz
                  -root # cd UUID-0.04
                  -root # perl Makefile.PL
                  -root # make && make install
                  -
                  -
                  -

                  Nous avons notre environnement prêt pour l’installation du SDK VMWare.

                  -

                  Télécharger la dernière version, correspondant à votre architecture 32/64 bits, sur le site officiel de VMWare (SDK VMWare)

                  -

                  Installer le SDK Perl VMWare:

                  -
                  root # tar zxvf VMware-vSphere-Perl-SDK-5.1.0-780721.x86_64.tar.gz
                  -root # cd vmware-vsphere-cli-distrib
                  -root # perl Makefile.pl
                  -root # make && make install
                  -
                  -
                  -
                  -
                  -

                  Installation de modules complémentaires¶

                  -

                  Certains modules complémentaires Perl peuvent être installés si vous souhaitez utiliser certaines fonctionnalités du centreon_esxd :

                  -

                  Pour envoyer les logs au daemon « syslog Â», il est nécessaire d’installer le module « Unix::Syslog »:

                  -
                  root # cpan install Unix::Syslog
                  -
                  -
                  -

                  Pour vérifier la date des snapshots d’une machine virtuelle, il est nécessaire d’installer le module « DateTime::Format::ISO8601 Â» ( ce module installe beaucoup de modules CPAN et est difficilement installable sans mettre à jour globalement « Perl Â». Cette mise à jour est très risqué ):

                  -
                  root # cpan install DateTime
                  -root # cpan install DateTime::Format::ISO8601
                  -root # o conf make /usr/bin/make
                  -root # o conf commit
                  -
                  -
                  -

                  Ensuite redémarrer votre système.

                  -
                  -
                  -

                  Installation de centreon-esxd¶

                  -

                  Télécharger l’archive de « centreon-esxd Â».

                  -

                  Installer les fichiers:

                  -
                  root # tar zxvf centreon-esxd-1.X.tar.gz
                  -root # cd centreon-esxd-1.X
                  -root # cp centreon_esxd /usr/bin/
                  -
                  -root # mkdir -p /etc/centreon
                  -root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm
                  -root # cp centreon_esxd-init /etc/init.d/centreon_esxd
                  -
                  -root # mkdir -p /usr/share/centreon/lib/centreon-esxd
                  -root # cp lib/* /usr/share/centreon/lib/centreon-esxd/
                  -
                  -
                  -

                  Activer le daemon « centreon-esxd Â» au démarrage:

                  -
                  root # chkconfig --level 2345 centreon_esxd on
                  -
                  -
                  -

                  Le plugin « nagios Â» correspond au fichier « centreon_esx_client.pl Â».

                  -
                  -
                  -
                  - - -
                  -
                  -
                  - -
                  -
                  - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/objects.inv b/connectors/vmware/doc/fr/_build/html/objects.inv deleted file mode 100644 index 6b9e7d70341d5f6891429e463885b3a060ed17b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 209 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~KjbN*1L8MO}j< zT!0c`5JgrBhI$4-Zb(L|LQ!gNVrE`SYLP;InnFoNX0bwAW=^UCkWS9eEhtJYE>2BR zC@s#+OIN7M$xPDYs - - - - - - - Search — Centreon ESXD 1.0.0 documentation - - - - - - - - - - - - - - - - - - - -
                  -
                  -
                  -
                  - -

                  Search

                  -
                  - -

                  - Please activate JavaScript to enable the search - functionality. -

                  -
                  -

                  - From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing fewer words won't appear in the result list. -

                  -
                  - - - -
                  - -
                  - -
                  - -
                  -
                  -
                  -
                  -
                  -
                  -
                  -
                  -
                  - - - - \ No newline at end of file diff --git a/connectors/vmware/doc/fr/_build/html/searchindex.js b/connectors/vmware/doc/fr/_build/html/searchindex.js deleted file mode 100644 index 6a665ac86..000000000 --- a/connectors/vmware/doc/fr/_build/html/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({envversion:42,terms:{"2iop":2,code:[],check_merethis_vmware_datastorio:2,trl_lun2:2,librairi:2,global:[1,2],troi:2,yellow:2,"\u00e9clat\u00e9":2,fourni:2,row:[],indicateur:2,"27iop":2,init:1,"surallou\u00e9":2,aux:2,valeur:2,"d\u00e9j\u00e0":2,sond:2,"valid\u00e9":1,"22743040o":2,sont:[1,2],garder:2,check_merethis_vmware_nethost:2,level:1,"d\u00e9marrag":1,servic:[],x86_64:1,visualis:2,"362747904o":2,"derni\u00e8r":1,direct:2,syslog:[1,2],second:2,pass:2,port:2,vmware:[],supervis:2,"_hostvcnam":2,section:[],quelqu:2,statushost:2,riops_lun1:2,communiqu:2,version:1,sur:[1,2],peuvent:[1,2],net:1,cela:[1,2],"charg\u00e9":2,"contr\u00f4ler":2,voici:2,snapshost:2,bodi:[],solari:1,"fonctionnalit\u00e9":1,modifi:2,valu:2,"m\u00eame":1,"tr\u00e8":1,search:[0,1],"v\u00e9rific":1,"r\u00e9cup\u00e8r":2,beaucoup:1,host:2,datetim:1,action:2,que:[1,2],environn:[],"risqu\u00e9":1,modul:[],souhaitez:[1,2],unix:[1,2],instal:[],total:2,"1773761536o":2,commun:2,lwp:1,pourcentag:2,perl:[],latenc:2,overhead:2,rhel:[],vcenter:2,type:2,more:1,ensuit:[1,2],riop:2,check_merethis_vmware_cpuhost:2,log_daemon:2,filtrer:2,check_merethis_vmware_datastoresvm:2,iso8601:1,warn:2,twl_lun2:2,twl_lun1:2,moin:2,cach:2,"rattach\u00e9":2,augment:1,car:2,uniqu:2,pour:[1,2],minimum:1,taux:2,nagio:1,root:1,"506574405632o":2,tar:1,requi:[],share:[1,2],check_merethis_vmware_swaphost:2,templat:2,critic:2,unzip:1,check_merethis_vmware_healthhost:2,"r\u00e9pons":2,traffic_out:2,suivant:2,gcc:1,refresh_keeper_sess:2,"totalit\u00e9":2,rapport:2,write:[],toolsnotinstal:2,optimal:2,xxxx:2,swap_in:2,mac:2,attent:2,mai:[1,2],datastoresvm:2,datastor:[],"remont\u00e9":2,souci:2,permet:2,light:2,timeout_kil:2,correspond:[1,2],allon:1,issu:2,inform:2,ensembl:2,make:1,"m\u00e9moir":[1,2],"d\u00e9faut":[1,2],offici:[],peut:[1,2],"00mhz":2,afin:2,"h\u00e9bergeant":2,kbp:2,jnh:1,"r\u00e9colter":2,"_servicethreshold":2,uuid:1,window:1,"\u00e9critur":2,memhost:2,nom:[1,2],non:1,"syst\u00e8m":[1,2],handl:2,dan:1,taill:2,devel:1,"\u00e9galement":2,effectu:[1,2],autr:1,optionnel:2,nou:1,"1jour":2,"bas\u00e9":2,critiqu:2,name:2,aucun:[1,2],temps_cour:2,"install\u00e9":1,check_merethis_vmware_datastoreusag:2,timeout:2,champ:2,cett:[1,2],espac:2,"cr\u00e9er":2,connect:2,"r\u00e9seau":2,distrib:1,our:2,"probl\u00e8m":2,variabl:2,respectiv:2,mettr:1,"nomm\u00e9":2,content:0,"\u00e9cout":2,traffic_in:2,centreon_esxd:[1,2],red:2,serveur:[1,2],"contr\u00f4l":1,check_merethis_vmware_maintenancehost:2,e2fsprog:1,qui:[1,2],org:1,selon:2,contient:2,libuuid:1,openssl:1,filter:2,liaison:2,yum:1,unknown:2,processeur:2,"r\u00e9sultat":2,"pr\u00e9sent\u00e9":1,check_merethis_vmware_countvmhost:2,mise:1,"pr\u00e9":[],votr:1,affich:2,donc:1,"indiqu\u00e9":2,crit:2,virtualcent:2,tou:2,ont:2,size:2,fonctionn:[],"_hostesxdport":2,mkdir:1,trl_lun1:2,nethost:2,"final":2,shell:[],option:2,"poss\u00e8d":2,cpu2:2,cpu3:2,specifi:2,cpu1:2,"d\u00e9pend":[1,2],date:[1,2],centreon_esx_cli:[1,2],ssl3_get_record:2,"00iop":2,older:2,wiops_lun2:2,wiops_lun1:2,timeout_vspher:2,ressourc:[1,2],sera:2,"red\u00e9marr":1,cpu_total_mhz:2,"acc\u00e8":2,aussi:2,myvmnam:2,"56196403200o":2,wiop:2,jour:1,lib:[1,2],min:2,hostvcnam:2,"d\u00e9connexion":2,libpath:2,fonction:1,deux:2,soap:[1,2],simplifi:2,macro:2,"sp\u00e9cifier":2,index:0,usernam:2,"configur\u00e9":2,plat:2,doit:2,dessu:2,maintenancehost:2,cpu0:2,"v\u00e9rifier":1,toolsnotrun:2,"class":1,url:2,request:2,snapshot:1,"_servicedsnam":2,"68705865728o":2,"\u00e9tat":2,vcname:2,"n\u00e9cessair":[1,2],"cr\u00e9\u00e9":2,text:[],session:2,threshold:2,identifi:2,trop:2,retrouv:2,xml:1,fichier:[1,2],menu:2,activ:[1,2],"cr\u00e9ant":2,"70148096o":2,"diff\u00e9rent":2,"s\u00e9par\u00e9":2,yml:[],count:2,cpuvm:2,ssl:2,mainten:1,"pr\u00eat":1,"t\u00e9l\u00e9chargement":1,vsphere_serv:2,"172032b":2,"2147483648o":2,snapshotvm:2,grai:2,bad:2,write_r:2,"\u00e9vite":2,"caract\u00e8r":2,swap_out:2,riops_lun2:2,"643976658944o":2,"_servicecrit":2,"recommand\u00e9":2,fail:2,sen:2,xxxxx:2,sorti:2,nombr:[1,2],vont:2,"_servicewarn":2,attribut:[],parent:2,check_merethis_vmware_memhost:2,officiel:1,comm:2,avon:1,cli:1,plugin:[1,2],"sp\u00e9cifi\u00e9":2,etc:[1,2],erreur:2,rend:1,login:2,"allou\u00e9":2,"d\u00e9conseill\u00e9":2,makefil:1,"d\u00e9finit":2,perfdata:2,"d\u00e9finir":2,linux:1,connexion:2,aller:2,json:[],"pr\u00e9sent":2,difficil:1,datastoreshost:2,cpu_tot:2,xxx:2,demand:[1,2],viperltoolkit:[],toolsvm:2,"entr\u00e9":2,"ais\u00e9":1,"_hostesxdhost":2,error:2,"1408f119":2,stdout:2,envoy:1,expat:1,"4561920o":2,"allum\u00e9":2,"00m":2,vou:[1,2],libxml:1,archiv:1,cento:[],conf:1,chkconfig:1,situ:2,par:[1,2],develop:[],log_crit:2,author:1,perform:2,balloon:2,memvm:2,"pr\u00e9senc":2,"ex\u00e9cut":2,"imp\u00e9rativ":2,traiter:2,grand:2,lite:1,http:[1,2],ouvr:2,nic:2,nicnam:2,vieux:2,moyen:2,"h\u00f4te":[],com:[],notr:1,"r\u00e9cup\u00e9rer":2,traffic_:2,client:2,command:[],titl:[],san:[1,2],programm:2,"g\u00e9n\u00e8re":2,protocol:[1,2],physiqu:2,tcp:2,processu:2,ayant:2,connecteur:1,bit:1,"renvoy\u00e9":2,site:1,virgul:2,toolsold:2,exempl:2,"cibl\u00e9":2,bloc:[],log_facil:2,enfin:2,check_merethis_vmware_snapshotvm:2,adress:2,esxdhost:2,bin:1,xxxxxx:2,format:1,read:2,mot:2,cpan:[],remont:2,check_merethis_vmware_datastoreshost:2,healthhost:2,password:2,daemon:[1,2],header:[],fournir:2,"d\u00e9fini":2,dsname:2,noth:2,collect:1,"pr\u00e9alabl":2,page:0,"r\u00f4le":2,www:[],besoin:2,swap_:2,interv:2,seuil:2,"14344192b":2,log_mod:2,hostesxdhost:2,bloqu:2,"n\u00e9cessit":2,ouvert:2,tmp:2,est:[1,2],swaphost:2,octet:2,esx:[],retri:2,avoir:2,minimal:1,machin:1,plu:2,sensibl:1,ancien:2,usag:[],virtuel:1,"test\u00e9":1,wget:1,"\u00eatre":[1,2],column:[],commit:1,"donn\u00e9":2,zxvf:1,routin:2,read_rat:2,vsphere:[1,2],son:[1,2],lier:2,"archiv\u00e9":1,sou:2,retourn:2,lieu:2,mymeta:[],testvc:2,log:[1,2],plusieur:2,support:[],logiciel:[],lor:2,esx1:2,interfac:2,comport:2,"1589248b":2,methodmak:1,usr:[1,2],lun2:2,lun1:2,pleinement:2,form:2,link:[],cpuhost:2,sdk:[],info:2,vive:1,temp:2,possibl:2,"default":2,avec:2,record:2,"cha\u00een":2,notam:2,vmnic0:2,"s\u00e9rie":2,user1:2,certain:1,utilis:[1,2],decrypt:2,lectur:2,"m\u00e9triqu":2,file:2,dessou:2,"mod\u00e8l":[],hostesxdport:2,commenc:1,"occup\u00e9":2,courant:2,check_merethis_vmware_statushost:2,crypt:1,seul:2,"_servicenicnam":2,normal:2,viell:2,test:[1,2],snaphost:2,architectur:[1,2],countvmhost:2,check_merethis_vmware_toolsvm:2,cpu0_mhz:2,hostaddress:2,"param\u00e8tr":2,check_merethis_vmware_cpuvm:2,lanc:2,niveau:2,exclu:1,ssleai:1,descript:2,check_merethis_vmware_memvm:2,"598016b":2,esxdport:2,"t\u00e9l\u00e9charger":1,cpu:1},objtypes:{},objnames:{},filenames:["index","installation/index","exploitation/index"],titles:["Welcome to Centreon ESXD’s documentation!","Installation","Exploitation"],objects:{},titleterms:{configur:2,modul:1,requi:1,"pr\u00e9":1,"contr\u00f4l":2,indic:0,exploit:2,cento:1,tabl:0,instal:1,"cr\u00e9ation":2,connecteur:2,check:2,vmware:[1,2],centreon:[0,1,2],reseau:2,welcom:0,"mod\u00e8l":2,titl:[],section:[],"mat\u00e9riel":1,logiciel:1,perl:1,health:2,rhel:1,optimisationd:[],document:0,memoir:2,attribut:2,machin:2,swap:2,statut:2,dan:2,usag:2,"identit\u00e9":2,"pr\u00e9conis":1,"h\u00f4te":2,"g\u00e9n\u00e9riqu":2,mainten:2,cpan:[],datastor:2,fonctionn:2,countvm:2,sdk:1,vmtool:2,esxd:[0,1,2],"compl\u00e9mentair":1,optimis:2,command:2,troubleshoot:2,"g\u00e9n\u00e9raux":2,list:2,virtuel:2,"pr\u00e9sentat":2,princip:2,snapshot:2,mode:2,esx:2,fich:2,servic:2,cpu:2,environn:1}}) \ No newline at end of file From bf01d8ae75c24e7e13364de140c3120b9b69721f Mon Sep 17 00:00:00 2001 From: qdelance Date: Wed, 14 May 2014 11:48:16 +0200 Subject: [PATCH 082/447] Add a warning for centreon 2.4 (ESXD unsupported) --- connectors/vmware/doc/en/installation/index.rst | 7 +++++-- connectors/vmware/doc/fr/installation/index.rst | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index cac06bda4..1d6b0be3c 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -15,11 +15,14 @@ Installation on other system is possible but is outside the scope of this docume Software Version ==================== ===================== VMWare SDK Perl 5.1 -Perl 5.8 +Perl 5.8 centreon-esxd 1.4 centreon-common-perl 2.5 ==================== ===================== +.. warning:: + The "centreon-esxd" RPMS provided by Merethis is designed to work with Centreon 2.5 (CES 2.2 or CES 3), it does not work with Centreon 2.4. + Hardware Recommandations ```````````````````````` @@ -144,4 +147,4 @@ Configure "centreon-esxd" daemon to start at boot :: root # chkconfig --level 2345 centreon_esxd on -*"centreon_esx_client.pl" is the corresponding nagios plugin.* \ No newline at end of file +*"centreon_esx_client.pl" is the corresponding nagios plugin.* diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index 73912e6a5..145f3e97f 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -20,6 +20,9 @@ centreon-esxd 1.5.4 perl-centreon-base 2.5.0 ==================== ===================== +.. warning:: + Le connecteur "centreon-esxd" fourni par Merethis est conçu pour fonctionner Centreon 2.5 (CES 2.2 ou CES 3), il ne fonctionne pas avec Centreon 2.4. + Préconisations matérielles `````````````````````````` From 9f62ad6051bd03948ec1e0ec61f47faa8f2ae5f9 Mon Sep 17 00:00:00 2001 From: qdelance Date: Thu, 15 May 2014 15:41:51 +0200 Subject: [PATCH 083/447] Extra doc for multiple VSphere (#6913) + fix EN doc --- .../vmware/doc/en/exploitation/index.rst | 29 +++++++++++++++++-- .../vmware/doc/fr/exploitation/index.rst | 19 +++++++++--- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/connectors/vmware/doc/en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst index c0db0f76e..6db7b05fc 100644 --- a/connectors/vmware/doc/en/exploitation/index.rst +++ b/connectors/vmware/doc/en/exploitation/index.rst @@ -38,7 +38,7 @@ The "centreon-esxd" program only works in "daemon" mode (a client is needed). Connector configuration ----------------------- -Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: +The « centreon-esxd » daemon is configured with the « centreon_esxd.pm » configuration file :: %centreonesxd_config = ( vsphere_server => { @@ -48,5 +48,30 @@ Le daemon « centreon-esxd » possède un fichier de configuration « centreo } ); -« vsphere_server » attribute configure VirtualCenter access. +« vsphere_server » attribute configures VirtualCenter access. +In case you have many VirtualCenters, the configuration is (note the use of "," as a separator) :: + + %centreonesxd_config = ( + vsphere_server => { + 'default' => {'url' => 'https://vcenter/sdk', + 'username' => 'test@test.fr', + 'password' => 'xxxx'}, + }, + 'other' => {'url' => 'https://other_vcenter/sdk', + 'username' => 'test@test.fr', + 'password' => 'xxxx'}, + } + ); + + +Troubleshooting +--------------- + +It is possible to get this kind of errors in the « logs » of « centreon-esxd » :: + + ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... + +VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. + +It is necessary to create an incident in case there are too many connections error between the daemon and the VirtualCenter. diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index a8ffa66ef..ca75ea1c9 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -50,11 +50,25 @@ Le daemon « centreon-esxd » possède un fichier de configuration « centreo ); L'attribut « vsphere_server » permet de configurer les accès aux différents VirtualCenter. +Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter la "," de séparation) :: + + %centreonesxd_config = ( + vsphere_server => { + 'default' => {'url' => 'https://vcenter/sdk', + 'username' => 'test@test.fr', + 'password' => 'xxxx'}, + }, + 'other' => {'url' => 'https://other_vcenter/sdk', + 'username' => 'test@test.fr', + 'password' => 'xxxx'}, + } + ); + Troubleshooting --------------- -Il est possible de retrouver des erreurs de ce type dans les « log » de « centreon-esxd » :: +Il est possible de retrouver des erreurs de ce type dans les « logs » de « centreon-esxd » :: ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... @@ -62,6 +76,3 @@ Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. - - - From c9982490d5ac330e4b542943a0b4d90c6bb91a0d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 18 Jul 2014 13:11:29 +0200 Subject: [PATCH 084/447] Fix 100% Cpu main process when a child is killed --- connectors/vmware/centreon_esx_client.pl | 2 +- connectors/vmware/centreonesxd.pm | 92 ++++++++++++++++-------- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 0be2faa79..d4f3501ef 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.5.3"; +my $VERSION = "1.5.5"; my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); my $socket; my $separatorin = '~'; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index 6caf7becc..c8b3cb488 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -20,7 +20,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); -my $VERSION = "1.5.3"; +my $VERSION = "1.5.5"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', @@ -240,6 +240,29 @@ sub load_module { } } +sub verify_child_vsphere { + my $self = shift; + + # Don't need that. We need to quit. Don't want to recreate sub-process :) + return if ($self->{stop} != 0); + + # Some dead process. need to relaunch it + foreach (keys %{$self->{return_child}}) { + delete $self->{return_child}->{$_}; + if (defined($self->{centreonesxd_config}->{vsphere_server}->{$_})) { + $self->{logger}->writeLogError("Sub-process for '" . $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} . "' dead ???!! We relaunch it"); + + close $self->{centreonesxd_config}->{vsphere_server}->{ $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} }->{writer_two}; + close $self->{centreonesxd_config}->{vsphere_server}->{ $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} }->{reader_one}; + delete $self->{filenos}->{ $self->{centreonesxd_config}->{vsphere_server}->{$_}->{fd} }; + $self->{read_select}->remove($self->{centreonesxd_config}->{vsphere_server}->{$_}->{fd}); + + $self->create_vsphere_child(vsphere_name => $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name}); + delete $self->{centreonesxd_config}->{vsphere_server}->{$_}; + } + } +} + sub verify_child { my $self = shift; my $progress = 0; @@ -423,6 +446,39 @@ sub vsphere_handler { } } +sub create_vsphere_child { + my ($self, %options) = @_; + + $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); + my ($reader_pipe_one, $writer_pipe_one); + my ($reader_pipe_two, $writer_pipe_two); + $self->{whoaim} = $options{vsphere_name}; + + 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; + $self->{centreonesxd_config}->{vsphere_server}->{$self->{child_vpshere_pid}} = { name => $self->{whoaim}, fd => fileno(${$self->{centreonesxd_config}->{vsphere_server}->{$options{vsphere_name}}->{reader_one}})}; + close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{writer_one}; + close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{reader_two}; + + $self->{filenos}->{fileno(${$self->{centreonesxd_config}->{vsphere_server}->{$options{vsphere_name}}->{reader_one}})} = 1; + $self->{read_select}->add(${$self->{centreonesxd_config}->{vsphere_server}->{$options{vsphere_name}}->{reader_one}}); +} + sub run { my $self = shift; @@ -444,38 +500,13 @@ sub run { ## # 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}}); + $self->create_vsphere_child(vsphere_name => $_); } + my $socket_fileno = fileno($server); $self->{logger}->writeLogInfo("[Server accepting clients]"); while (1) { @@ -568,6 +599,9 @@ sub run { } } + # Check if there some dead sub-process. + $self->verify_child_vsphere(); + # Verify socket foreach (keys %{$self->{sockets}}) { if (time() - $self->{sockets}->{$_}->{ctime} > $self->{centreonesxd_config}->{timeout}) { From 9de2bc5145de9f6eb4b04cf3c502fb1f13a3225a Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 18 Jul 2014 13:35:21 +0200 Subject: [PATCH 085/447] Fix #7214 --- connectors/vmware/lib/cmddatastoresnapshots.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/lib/cmddatastoresnapshots.pm b/connectors/vmware/lib/cmddatastoresnapshots.pm index 4f2034a6c..ac804f17d 100644 --- a/connectors/vmware/lib/cmddatastoresnapshots.pm +++ b/connectors/vmware/lib/cmddatastoresnapshots.pm @@ -23,7 +23,7 @@ sub getCommandName { sub checkArgs { my $self = shift; - my ($ds, $warn, $crit, $warn2, $crit2) = @_; + my ($ds, $filter, $warn, $crit, $warn2, $crit2) = @_; if (!defined($ds) || $ds eq "") { $self->{logger}->writeLogError("ARGS error: need datastore name"); From 9618d5e7714d94aee788cd26e3da040d4c2ebe3b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 18 Aug 2014 11:35:46 +0200 Subject: [PATCH 086/447] Fix #7119 #7254 #7292 --- connectors/vmware/centreon_esx_client.pl | 30 +++--- connectors/vmware/centreonesxd.pm | 2 +- connectors/vmware/lib/cmdhealthhost.pm | 116 +++++++++++++++-------- connectors/vmware/lib/cmdmemvm.pm | 16 ++-- connectors/vmware/lib/cmdtoolsvm.pm | 6 ++ 5 files changed, 110 insertions(+), 60 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index d4f3501ef..dc76dca10 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -6,7 +6,7 @@ use IO::Socket; use Getopt::Long; my $PROGNAME = $0; -my $VERSION = "1.5.5"; +my $VERSION = "1.5.6"; my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); my $socket; my $separatorin = '~'; @@ -37,6 +37,8 @@ my %OPTION = ( check_disk_limit => undef, details_value => undef, + storage_status => undef, + # For Autodisco xml => undef, show_attributes => undef, @@ -81,6 +83,8 @@ GetOptions( "details-value:s" => \$OPTION{details_value}, + "storage-status" => \$OPTION{storage_status}, + "xml" => \$OPTION{xml}, "show-attributes" => \$OPTION{show_attributes}, ); @@ -111,6 +115,7 @@ sub print_usage () { print "\n"; print "'healthhost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; + print " --storage-status Check storage of ESX\n"; print "\n"; print "'maintenancehost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; @@ -198,9 +203,10 @@ sub print_usage () { print " --critical2 Critical Threshold in percent for cpu ready (default 10)\n"; print "\n"; print "'toolsvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; + print " --vm VM to check (required)\n"; + print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; + print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; + print " --skip-not-running Skip vmtools for vms not running (also template)\n"; print "\n"; print "'snapshotvm':\n"; print " --vm VM to check (required)\n"; @@ -209,7 +215,7 @@ sub print_usage () { print " --critical Critical threshold in seconds (default: 5 days)\n"; print " --check-consolidation Check if VM needs consolidation (since vsphere 5.0)\n"; print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; - print " --skip-not-running Skip snapshots from vms not running\n"; + print " --skip-not-running Skip snapshots for vms not running\n"; print "\n"; print "'limitvm':\n"; print " --vm VM to check (required)\n"; @@ -226,8 +232,8 @@ sub print_usage () { print "\n"; print "'memvm':\n"; print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; + print " -w (--warning) Warning Threshold in percent\n"; + print " -c (--critical) Critical Threshold in percent\n"; print "\n"; print "'swapvm':\n"; print " --vm VM to check (required)\n"; @@ -326,12 +332,13 @@ sub healthhost_check_arg { print_usage(); exit $ERRORS{UNKNOWN}; } + $OPTION{storage_status} = (defined($OPTION{storage_status}) ? 1 : 0); return 0; } sub healthhost_get_str { return join($separatorin, - ('healthhost', $OPTION{vsphere}, $OPTION{'esx-host'})); + ('healthhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{storage_status})); } sub datastoreusage_check_arg { @@ -627,12 +634,13 @@ sub toolsvm_check_arg { } $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); + $OPTION{skip_not_running} = (defined($OPTION{skip_not_running}) ? 1 : 0); return 0; } sub toolsvm_get_str { return join($separatorin, - ('toolsvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{skip_errors})); + ('toolsvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{skip_errors}, $OPTION{skip_not_running})); } sub snapshotvm_check_arg { @@ -709,10 +717,10 @@ sub memvm_check_arg { exit $ERRORS{UNKNOWN}; } if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; + $OPTION{warning} = ''; } if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; + $OPTION{critical} = ''; } return 0; } diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index c8b3cb488..d103bab2a 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -20,7 +20,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); -my $VERSION = "1.5.5"; +my $VERSION = "1.5.6"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', diff --git a/connectors/vmware/lib/cmdhealthhost.pm b/connectors/vmware/lib/cmdhealthhost.pm index 82bc8e1ed..26a1cfc40 100644 --- a/connectors/vmware/lib/cmdhealthhost.pm +++ b/connectors/vmware/lib/cmdhealthhost.pm @@ -35,13 +35,14 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lhost} = $_[0]; + $self->{storage_status} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; } sub run { my $self = shift; my %filters = ('name' => $self->{lhost}); - my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', + my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { @@ -49,7 +50,7 @@ sub run { } return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); + $$result[0]->{'runtime.connectionState'}->val) == 0); my $status = 0; # OK my $output_critical = ''; @@ -62,49 +63,84 @@ sub run { my $CAlertCount = 0; my $WAlertCount = 0; foreach my $entity_view (@$result) { - my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo.cpuStatusInfo'}; + my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{cpuStatusInfo}; + my $memoryStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{memoryStatusInfo}; + my $storageStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{storageStatusInfo}; my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; - if (!defined($cpuStatusInfo)) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "API error - unable to get cpuStatusInfo"); - } - if (!defined($numericSensorInfo)) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "API error - unable to get numericSensorInfo"); - } - + # CPU - foreach (@$cpuStatusInfo) { - if ($_->status->key =~ /^red$/i) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $CAlertCount++; - } elsif ($_->status->key =~ /^yellow$/i) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $WAlertCount++; - } else { - $OKCount++; + if (defined($cpuStatusInfo)) { + foreach (@$cpuStatusInfo) { + if ($_->status->key =~ /^red$/i) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $CAlertCount++; + } elsif ($_->status->key =~ /^yellow$/i) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $WAlertCount++; + } else { + $OKCount++; + } } } + + # Memory + if (defined($memoryStatusInfo)) { + foreach (@$memoryStatusInfo) { + if ($_->status->key =~ /^red$/i) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $CAlertCount++; + } elsif ($_->status->key =~ /^yellow$/i) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $WAlertCount++; + } else { + $OKCount++; + } + } + } + + # Storage + if ($self->{storage_status} == 1 && defined($storageStatusInfo)) { + foreach (@$storageStatusInfo) { + if ($_->status->key =~ /^red$/i) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $CAlertCount++; + } elsif ($_->status->key =~ /^yellow$/i) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + $_->name . ": " . $_->status->summary); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $WAlertCount++; + } else { + $OKCount++; + } + } + } + # Sensor - foreach (@$numericSensorInfo) { - if ($_->healthState->key =~ /^red$/i) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $CAlertCount++; - } elsif ($_->healthState->key =~ /^yellow$/i) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $WAlertCount++; - } else { - $OKCount++; + if (defined($numericSensorInfo)) { + foreach (@$numericSensorInfo) { + if ($_->healthState->key =~ /^red$/i) { + centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $CAlertCount++; + } elsif ($_->healthState->key =~ /^yellow$/i) { + centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", + $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); + $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $WAlertCount++; + } else { + $OKCount++; + } } } } diff --git a/connectors/vmware/lib/cmdmemvm.pm b/connectors/vmware/lib/cmdmemvm.pm index 3740cad31..9bface947 100644 --- a/connectors/vmware/lib/cmdmemvm.pm +++ b/connectors/vmware/lib/cmdmemvm.pm @@ -29,15 +29,15 @@ sub checkArgs { $self->{logger}->writeLogError("ARGS error: need vm name"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + if (defined($warn) && $warn ne '' && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); return 1; } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { + if (defined($crit) && $crit ne '' && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { + if (defined($warn) && defined($crit) && $warn ne '' && $crit ne '' && $warn > $crit) { $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); return 1; } @@ -47,8 +47,8 @@ sub checkArgs { sub initArgs { my $self = shift; $self->{lvm} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 80); - $self->{crit} = (defined($_[2]) ? $_[2] : 90); + $self->{warn} = (defined($_[1]) ? $_[1] : undef); + $self->{crit} = (defined($_[2]) ? $_[2] : undef); } sub run { @@ -91,15 +91,15 @@ sub run { my $status = 0; # OK my $output = ''; - if ($mem_consumed * 100 / ($memory_size / 1024) >= $self->{warn}) { + if (defined($self->{warn}) && $mem_consumed * 100 / ($memory_size / 1024) >= $self->{warn}) { $status = centreon::esxd::common::errors_mask($status, 'WARNING'); } - if ($mem_consumed * 100 / ($memory_size / 1024) >= $self->{crit}) { + if (defined($self->{crit}) && $mem_consumed * 100 / ($memory_size / 1024) >= $self->{crit}) { $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); } $output = "Memory usage : " . centreon::esxd::common::simplify_number($mem_consumed / 1024 / 1024) . " Go - size : " . centreon::esxd::common::simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . centreon::esxd::common::simplify_number($mem_consumed * 100 / ($memory_size / 1024)) . " %"; - $output .= "|usage=" . ($mem_consumed * 1024) . "o;" . centreon::esxd::common::simplify_number($memory_size * $self->{warn} / 100, 0) . ";" . centreon::esxd::common::simplify_number($memory_size * $self->{crit} / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o" . " ballooning=" . ($mem_ballooning * 1024) . "o" . " shared=" . ($mem_shared * 1024) . "o" . " active=" . ($mem_active * 1024) . "o" ; + $output .= "|usage=" . ($mem_consumed * 1024) . "o;" . (defined($self->{warn}) ? centreon::esxd::common::simplify_number($memory_size * $self->{warn} / 100, 0) : '') . ";" . (defined($self->{crit}) ? centreon::esxd::common::simplify_number($memory_size * $self->{crit} / 100, 0) : '') . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o" . " ballooning=" . ($mem_ballooning * 1024) . "o" . " shared=" . ($mem_shared * 1024) . "o" . " active=" . ($mem_active * 1024) . "o" ; $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } diff --git a/connectors/vmware/lib/cmdtoolsvm.pm b/connectors/vmware/lib/cmdtoolsvm.pm index b749f46a2..4daabaa5a 100644 --- a/connectors/vmware/lib/cmdtoolsvm.pm +++ b/connectors/vmware/lib/cmdtoolsvm.pm @@ -37,6 +37,7 @@ sub initArgs { $self->{lvm} = $_[0]; $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; $self->{skip_errors} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; + $self->{skip_not_running} = (defined($_[3]) && $_[3] == 1) ? 1 : 0; } sub run { @@ -77,6 +78,11 @@ sub run { } next; } + + if ($self->{skip_not_running} == 1 && + !centreon::esxd::common::is_running($virtual->{'runtime.powerState'}->val)) { + next; + } my $tools_status = lc($virtual->{'summary.guest.toolsStatus'}->val); if ($tools_status eq 'toolsnotinstalled') { From 8567bc38b5d36a39403d06d182b051edc2da98cb Mon Sep 17 00:00:00 2001 From: rwerquin Date: Tue, 7 Oct 2014 18:26:26 +0200 Subject: [PATCH 087/447] update index --- connectors/vmware/doc/en/index.rst | 8 -------- connectors/vmware/doc/fr/index.rst | 8 -------- 2 files changed, 16 deletions(-) diff --git a/connectors/vmware/doc/en/index.rst b/connectors/vmware/doc/en/index.rst index 8f840209e..14a3134a6 100644 --- a/connectors/vmware/doc/en/index.rst +++ b/connectors/vmware/doc/en/index.rst @@ -14,11 +14,3 @@ Contents: installation/index exploitation/index - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/connectors/vmware/doc/fr/index.rst b/connectors/vmware/doc/fr/index.rst index 8f840209e..14a3134a6 100644 --- a/connectors/vmware/doc/fr/index.rst +++ b/connectors/vmware/doc/fr/index.rst @@ -14,11 +14,3 @@ Contents: installation/index exploitation/index - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - From c47cda1b7c792af65b3311e678db5cc2ff5b1246 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 17 Oct 2014 17:33:33 +0200 Subject: [PATCH 088/447] + begin to work --- connectors/vmware/centreon_esxd | 2 + connectors/vmware/centreonesxd.pm | 281 ++++++++---------------------- 2 files changed, 78 insertions(+), 205 deletions(-) diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd index c63f3f893..aac3e5d2e 100644 --- a/connectors/vmware/centreon_esxd +++ b/connectors/vmware/centreon_esxd @@ -2,6 +2,8 @@ use warnings; use centreon::script::centreonesxd; +use FindBin; +use lib "$FindBin::Bin"; centreon::script::centreonesxd->new()->run(); diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/centreonesxd.pm index d103bab2a..7caa310cf 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/centreonesxd.pm @@ -5,9 +5,9 @@ package centreon::script::centreonesxd; use strict; use VMware::VIRuntime; use VMware::VILib; -use IO::Socket; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); use File::Basename; -use IO::Select; use POSIX ":sys_wait_h"; use Data::Dumper; use centreon::script; @@ -252,11 +252,6 @@ sub verify_child_vsphere { if (defined($self->{centreonesxd_config}->{vsphere_server}->{$_})) { $self->{logger}->writeLogError("Sub-process for '" . $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} . "' dead ???!! We relaunch it"); - close $self->{centreonesxd_config}->{vsphere_server}->{ $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} }->{writer_two}; - close $self->{centreonesxd_config}->{vsphere_server}->{ $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} }->{reader_one}; - delete $self->{filenos}->{ $self->{centreonesxd_config}->{vsphere_server}->{$_}->{fd} }; - $self->{read_select}->remove($self->{centreonesxd_config}->{vsphere_server}->{$_}->{fd}); - $self->create_vsphere_child(vsphere_name => $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name}); delete $self->{centreonesxd_config}->{vsphere_server}->{$_}; } @@ -266,17 +261,14 @@ sub verify_child_vsphere { 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"; + print "===timeout papa===\n"; + #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++; @@ -297,11 +289,13 @@ 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); + my $context = zmq_init(); + + my $backend = zmq_socket($context, ZMQ_DEALER); + #zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $self->{whoaim}); + #zmq_connect($backend, 'ipc://routing.ipc'); + #zmq_sendmsg($backend, 'ready'); + while (1) { my $progress = $self->verify_child(); @@ -320,8 +314,7 @@ sub vsphere_handler { eval { $self->{session1}->logout(); }; - } - print $handle_writer_pipe "STOPPED|$self->{whoaim}\n"; + } exit (0); } @@ -379,104 +372,46 @@ sub vsphere_handler { if ($self->{vsphere_connected} == 0) { sleep(5); } - if ($self->{stop} == 0) { - @rh_set = $self->{read_select}->can_read(30); - } else { + if ($self->{stop} != 0) { sleep(1); - $timeout_process++; - @rh_set = $self->{read_select}->can_read(0); + next; } - 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 $message = zmq_recvmsg($backend, ZMQ_DONTWAIT); + if (defined($message)) { + if ($self->{vsphere_connected}) { + $self->{logger}->writeLogInfo("vpshere '" . $self->{whoaim} . "' handler asking: $message"); - my ($id) = split(/\Q$self->{separatorin}\E/, $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 /\Q$self->{separatorin}\E/, $data_element; - $self->{global_id} = $id; - $self->{modules_registry}->{$name}->initArgs(@args); - $self->{modules_registry}->{$name}->run(); - exit(0); - } else { - # Parent - close $writer; - } - } else { - print $handle_writer_pipe "$id|-1|Vsphere connection error.\n"; + $self->{child_proc}->{pid} = fork; + if (!$self->{child_proc}->{pid}) { + # Child + $self->{logger}->{log_mode} = 1 if ($self->{logger}->{log_mode} == 0); + my ($id, $name, @args) = split /\Q$self->{separatorin}\E/, $data_element; + $self->{global_id} = $id; + $self->{modules_registry}->{$name}->initArgs(@args); + $self->{modules_registry}->{$name}->run(); + exit(0); } } 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}; + #print $handle_writer_pipe "$id|-1|Vsphere connection error.\n"; } - } + } } } sub create_vsphere_child { my ($self, %options) = @_; - $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); - my ($reader_pipe_one, $writer_pipe_one); - my ($reader_pipe_two, $writer_pipe_two); + $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); $self->{whoaim} = $options{vsphere_name}; - 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; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{child_vpshere_pid}} = { name => $self->{whoaim}, fd => fileno(${$self->{centreonesxd_config}->{vsphere_server}->{$options{vsphere_name}}->{reader_one}})}; - close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{writer_one}; - close $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{reader_two}; - - $self->{filenos}->{fileno(${$self->{centreonesxd_config}->{vsphere_server}->{$options{vsphere_name}}->{reader_one}})} = 1; - $self->{read_select}->add(${$self->{centreonesxd_config}->{vsphere_server}->{$options{vsphere_name}}->{reader_one}}); + $self->{centreonesxd_config}->{vsphere_server}->{$self->{child_vpshere_pid}} = { name => $self->{whoaim} }; } sub run { @@ -488,127 +423,63 @@ sub run { $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) { + my $context = zmq_init(); + my $frontend = zmq_socket($context, ZMQ_ROUTER); + + zmq_bind($frontend, 'tcp://*:5700'); + zmq_bind($frontend, 'ipc://routing.ipc'); + + if (!defined($frontend)) { $self->{logger}->writeLogError("Can't setup server: $!"); exit(1); } - - ## - # Create childs - ## - $self->{read_select} = new IO::Select(); - $self->{read_select}->add($server); foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { $self->create_vsphere_child(vsphere_name => $_); } - 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) { - # No childs - if (scalar(keys %{$self->{centreonesxd_config}->{vsphere_server}}) == 0) { - $self->{logger}->writeLogInfo("Quit main process"); - exit(0); - } - 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}) || $counter != $self->{sockets}->{$id}->{counter}) { - $self->{logger}->writeLogInfo("Too much time to get response."); - next; - } - - $self->{logger}->writeLogInfo("response = $data_element"); - $data_element =~ s/^.*?\|//; - centreon::esxd::common::response_client2($self, $id, $data_element . "\n"); - } else { - # Socket - my $line = <$rh>; - if (defined($line) && $line ne "") { - chomp $line; - my ($name, $vsphere_name, @args) = split /\Q$self->{separatorin}\E/, $line; + + # Initialize poll set + my @poll = ( + { + socket => $frontend, + events => ZMQ_POLLIN, + callback => sub { + while (1) { + # Process all parts of the message + my $message = zmq_recvmsg($frontend); + print "=== " . Data::Dumper::Dumper(zmq_msg_data($message)) . " ===\n"; + $message = zmq_recvmsg($frontend); + print "=== " . Data::Dumper::Dumper(zmq_msg_data($message)) . " ===\n"; + + my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); - if ($name eq 'stats') { - centreon::esxd::common::stats_info($self, $rh, $current_fileno, \@args); - next; - } - if (!defined($self->{modules_registry}->{$name})) { - centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Unknown method name '$name'\n"); - next; - } - if ($self->{modules_registry}->{$name}->checkArgs(@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} . $self->{separatorin} . $name . $self->{separatorin} . join($self->{separatorin}, @args) . "\n"; - } else { - centreon::esxd::common::response_client1($self, $rh, $current_fileno, "3|Need arguments\n"); + #zmq_sendmsg($backend, $message, $more ? ZMQ_SNDMORE : 0); + last unless $more; + return 1; } } - } + }, + ); - # Check if there some dead sub-process. - $self->verify_child_vsphere(); - - # Verify socket - foreach (keys %{$self->{sockets}}) { - if (time() - $self->{sockets}->{$_}->{ctime} > $self->{centreonesxd_config}->{timeout}) { - $self->{logger}->writeLogInfo("Timeout returns."); - centreon::esxd::common::response_client2($self, $_, "3|TIMEOUT\n"); - } - } + # Switch messages between sockets + while (1) { + #if ($self->{stop} == 1) { + # No childs + # if (scalar(keys %{$self->{centreonesxd_config}->{vsphere_server}}) == 0) { + # $self->{logger}->writeLogInfo("Quit main process"); + # exit(0); + # } + # foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { + # $self->{logger}->writeLogInfo("Send STOP command to '$_' child."); + # my $send_msg = zmq_msg_init_data($_ . " STOP"); + # zmq_msg_send($send_msg, $publisher, 0); + # } + # $self->{stop} = 2; + #} + + zmq_poll(\@poll, 1000); } } From 8479952a1affaaf16820a5b2f99bcbdab4ec4046 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 20 Oct 2014 11:49:29 +0200 Subject: [PATCH 089/447] Refs #7246 WIP --- .../centreon/esxd}/cmdcountvmhost.pm | 0 .../{lib => src/centreon/esxd}/cmdcpuhost.pm | 0 .../{lib => src/centreon/esxd}/cmdcpuvm.pm | 0 .../centreon/esxd}/cmddatastoreio.pm | 0 .../centreon/esxd}/cmddatastoreiops.pm | 0 .../centreon/esxd}/cmddatastoreshost.pm | 0 .../centreon/esxd}/cmddatastoresnapshots.pm | 0 .../centreon/esxd}/cmddatastoresvm.pm | 0 .../centreon/esxd}/cmddatastoreusage.pm | 0 .../{lib => src/centreon/esxd}/cmdgetmap.pm | 0 .../centreon/esxd}/cmdhealthhost.pm | 0 .../{lib => src/centreon/esxd}/cmdlimitvm.pm | 0 .../centreon/esxd}/cmdlistdatastore.pm | 0 .../{lib => src/centreon/esxd}/cmdlisthost.pm | 0 .../centreon/esxd}/cmdlistnichost.pm | 0 .../centreon/esxd}/cmdmaintenancehost.pm | 0 .../{lib => src/centreon/esxd}/cmdmemhost.pm | 0 .../{lib => src/centreon/esxd}/cmdmemvm.pm | 0 .../{lib => src/centreon/esxd}/cmdnethost.pm | 0 .../centreon/esxd}/cmdsnapshotvm.pm | 0 .../centreon/esxd}/cmdstatushost.pm | 0 .../{lib => src/centreon/esxd}/cmdswaphost.pm | 0 .../{lib => src/centreon/esxd}/cmdswapvm.pm | 0 .../centreon/esxd}/cmdthinprovisioningvm.pm | 0 .../{lib => src/centreon/esxd}/cmdtoolsvm.pm | 0 .../centreon/esxd}/cmduptimehost.pm | 0 .../{lib => src/centreon/esxd}/common.pm | 31 ++ .../{ => src/centreon/script}/centreonesxd.pm | 295 +++++++++++------- 28 files changed, 209 insertions(+), 117 deletions(-) rename connectors/vmware/{lib => src/centreon/esxd}/cmdcountvmhost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdcpuhost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdcpuvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmddatastoreio.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmddatastoreiops.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmddatastoreshost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmddatastoresnapshots.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmddatastoresvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmddatastoreusage.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdgetmap.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdhealthhost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdlimitvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdlistdatastore.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdlisthost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdlistnichost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdmaintenancehost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdmemhost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdmemvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdnethost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdsnapshotvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdstatushost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdswaphost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdswapvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdthinprovisioningvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmdtoolsvm.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/cmduptimehost.pm (100%) rename connectors/vmware/{lib => src/centreon/esxd}/common.pm (93%) rename connectors/vmware/{ => src/centreon/script}/centreonesxd.pm (56%) diff --git a/connectors/vmware/lib/cmdcountvmhost.pm b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm similarity index 100% rename from connectors/vmware/lib/cmdcountvmhost.pm rename to connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm diff --git a/connectors/vmware/lib/cmdcpuhost.pm b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm similarity index 100% rename from connectors/vmware/lib/cmdcpuhost.pm rename to connectors/vmware/src/centreon/esxd/cmdcpuhost.pm diff --git a/connectors/vmware/lib/cmdcpuvm.pm b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm similarity index 100% rename from connectors/vmware/lib/cmdcpuvm.pm rename to connectors/vmware/src/centreon/esxd/cmdcpuvm.pm diff --git a/connectors/vmware/lib/cmddatastoreio.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm similarity index 100% rename from connectors/vmware/lib/cmddatastoreio.pm rename to connectors/vmware/src/centreon/esxd/cmddatastoreio.pm diff --git a/connectors/vmware/lib/cmddatastoreiops.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm similarity index 100% rename from connectors/vmware/lib/cmddatastoreiops.pm rename to connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm diff --git a/connectors/vmware/lib/cmddatastoreshost.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreshost.pm similarity index 100% rename from connectors/vmware/lib/cmddatastoreshost.pm rename to connectors/vmware/src/centreon/esxd/cmddatastoreshost.pm diff --git a/connectors/vmware/lib/cmddatastoresnapshots.pm b/connectors/vmware/src/centreon/esxd/cmddatastoresnapshots.pm similarity index 100% rename from connectors/vmware/lib/cmddatastoresnapshots.pm rename to connectors/vmware/src/centreon/esxd/cmddatastoresnapshots.pm diff --git a/connectors/vmware/lib/cmddatastoresvm.pm b/connectors/vmware/src/centreon/esxd/cmddatastoresvm.pm similarity index 100% rename from connectors/vmware/lib/cmddatastoresvm.pm rename to connectors/vmware/src/centreon/esxd/cmddatastoresvm.pm diff --git a/connectors/vmware/lib/cmddatastoreusage.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm similarity index 100% rename from connectors/vmware/lib/cmddatastoreusage.pm rename to connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm diff --git a/connectors/vmware/lib/cmdgetmap.pm b/connectors/vmware/src/centreon/esxd/cmdgetmap.pm similarity index 100% rename from connectors/vmware/lib/cmdgetmap.pm rename to connectors/vmware/src/centreon/esxd/cmdgetmap.pm diff --git a/connectors/vmware/lib/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm similarity index 100% rename from connectors/vmware/lib/cmdhealthhost.pm rename to connectors/vmware/src/centreon/esxd/cmdhealthhost.pm diff --git a/connectors/vmware/lib/cmdlimitvm.pm b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm similarity index 100% rename from connectors/vmware/lib/cmdlimitvm.pm rename to connectors/vmware/src/centreon/esxd/cmdlimitvm.pm diff --git a/connectors/vmware/lib/cmdlistdatastore.pm b/connectors/vmware/src/centreon/esxd/cmdlistdatastore.pm similarity index 100% rename from connectors/vmware/lib/cmdlistdatastore.pm rename to connectors/vmware/src/centreon/esxd/cmdlistdatastore.pm diff --git a/connectors/vmware/lib/cmdlisthost.pm b/connectors/vmware/src/centreon/esxd/cmdlisthost.pm similarity index 100% rename from connectors/vmware/lib/cmdlisthost.pm rename to connectors/vmware/src/centreon/esxd/cmdlisthost.pm diff --git a/connectors/vmware/lib/cmdlistnichost.pm b/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm similarity index 100% rename from connectors/vmware/lib/cmdlistnichost.pm rename to connectors/vmware/src/centreon/esxd/cmdlistnichost.pm diff --git a/connectors/vmware/lib/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm similarity index 100% rename from connectors/vmware/lib/cmdmaintenancehost.pm rename to connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm diff --git a/connectors/vmware/lib/cmdmemhost.pm b/connectors/vmware/src/centreon/esxd/cmdmemhost.pm similarity index 100% rename from connectors/vmware/lib/cmdmemhost.pm rename to connectors/vmware/src/centreon/esxd/cmdmemhost.pm diff --git a/connectors/vmware/lib/cmdmemvm.pm b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm similarity index 100% rename from connectors/vmware/lib/cmdmemvm.pm rename to connectors/vmware/src/centreon/esxd/cmdmemvm.pm diff --git a/connectors/vmware/lib/cmdnethost.pm b/connectors/vmware/src/centreon/esxd/cmdnethost.pm similarity index 100% rename from connectors/vmware/lib/cmdnethost.pm rename to connectors/vmware/src/centreon/esxd/cmdnethost.pm diff --git a/connectors/vmware/lib/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm similarity index 100% rename from connectors/vmware/lib/cmdsnapshotvm.pm rename to connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm diff --git a/connectors/vmware/lib/cmdstatushost.pm b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm similarity index 100% rename from connectors/vmware/lib/cmdstatushost.pm rename to connectors/vmware/src/centreon/esxd/cmdstatushost.pm diff --git a/connectors/vmware/lib/cmdswaphost.pm b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm similarity index 100% rename from connectors/vmware/lib/cmdswaphost.pm rename to connectors/vmware/src/centreon/esxd/cmdswaphost.pm diff --git a/connectors/vmware/lib/cmdswapvm.pm b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm similarity index 100% rename from connectors/vmware/lib/cmdswapvm.pm rename to connectors/vmware/src/centreon/esxd/cmdswapvm.pm diff --git a/connectors/vmware/lib/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm similarity index 100% rename from connectors/vmware/lib/cmdthinprovisioningvm.pm rename to connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm diff --git a/connectors/vmware/lib/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm similarity index 100% rename from connectors/vmware/lib/cmdtoolsvm.pm rename to connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm diff --git a/connectors/vmware/lib/cmduptimehost.pm b/connectors/vmware/src/centreon/esxd/cmduptimehost.pm similarity index 100% rename from connectors/vmware/lib/cmduptimehost.pm rename to connectors/vmware/src/centreon/esxd/cmduptimehost.pm diff --git a/connectors/vmware/lib/common.pm b/connectors/vmware/src/centreon/esxd/common.pm similarity index 93% rename from connectors/vmware/lib/common.pm rename to connectors/vmware/src/centreon/esxd/common.pm index c71b749dc..147cb3f3d 100644 --- a/connectors/vmware/lib/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -6,11 +6,42 @@ use strict; use Data::Dumper; use VMware::VIRuntime; use VMware::VILib; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use centreon::plugins::options; +use centreon::plugins::output; +use centreon::plugins::perfdata; + +my $manager_display = {}; 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 init_response { + $manager_display->{options} = centreon::plugins::options->new(); + $manager_display->{output} = centreon::plugins::output->new(options => $manager_display->{options}); + $manager_display->{perfdata} = centreon::plugins::perfdata->new(output => $manager_display->{output}); + + return $manager_display; +} + +sub response { + my (%options) = @_; + + my $stdout; + { + local *STDOUT; + $manager_display->{output}->{option_results}->{output_json} = 1; + open STDOUT, '>', \$stdout; + $manager_display->{output}->display(force_long_output => 1); + } + + print "====stdout === $stdout===\n"; + zmq_sendmsg($options{endpoint}, $options{identity}, ZMQ_SNDMORE); + zmq_sendmsg($options{endpoint}, "RESPSERVER " . $stdout); +} + sub errors_mask { my ($status, $state) = @_; diff --git a/connectors/vmware/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm similarity index 56% rename from connectors/vmware/centreonesxd.pm rename to connectors/vmware/src/centreon/script/centreonesxd.pm index 7caa310cf..eecf6cea6 100644 --- a/connectors/vmware/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -13,6 +13,8 @@ use Data::Dumper; use centreon::script; use centreon::esxd::common; +my ($centreonesxd, $frontend, $backend); + BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; } @@ -85,8 +87,6 @@ sub new { } ); - $self->{session_id} = undef; - $self->{sockets} = {}; $self->{child_proc} = {}; $self->{return_child} = {}; $self->{vsphere_connected} = 0; @@ -100,14 +100,10 @@ sub new { $self->{perfcounter_speriod} = -1; $self->{stop} = 0; $self->{counter_request_id} = 0; - $self->{child_vpshere_pid} = undef; - $self->{read_select} = undef; + $self->{childs_vpshere_pid} = {}; $self->{session1} = undef; $self->{counter} = 0; - $self->{global_id} = undef; $self->{whoaim} = undef; # to know which vsphere to connect - $self->{separatorin} = '~'; - $self->{filenos} = {}; $self->{module_date_parse_loaded} = 0; $self->{modules_registry} = {}; @@ -243,19 +239,32 @@ sub load_module { sub verify_child_vsphere { my $self = shift; - # Don't need that. We need to quit. Don't want to recreate sub-process :) - return if ($self->{stop} != 0); - # Some dead process. need to relaunch it foreach (keys %{$self->{return_child}}) { delete $self->{return_child}->{$_}; - if (defined($self->{centreonesxd_config}->{vsphere_server}->{$_})) { - $self->{logger}->writeLogError("Sub-process for '" . $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name} . "' dead ???!! We relaunch it"); - - $self->create_vsphere_child(vsphere_name => $self->{centreonesxd_config}->{vsphere_server}->{$_}->{name}); - delete $self->{centreonesxd_config}->{vsphere_server}->{$_}; + + # We need to quit + if ($self->{stop} != 0) { + my $name = $self->{childs_vpshere_pid}->{$_}; + $self->{centreonesxd_config}->{vsphere_server}->{$name}->{running} = 0; + next; + } + + if (defined($self->{childs_vpshere_pid}->{$_})) { + $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' dead ???!! We relaunch it"); + $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}); + delete $self->{childs_vpshere_pid}->{$_}; } } + + my $count = 0; + foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { + if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{running} == 1) { + $count++; + } + } + + return $count; } sub verify_child { @@ -285,34 +294,112 @@ sub verify_child { return $progress; } +sub router_event { + while (1) { + # Process all parts of the message + my $message = zmq_recvmsg($frontend); + my $identity = zmq_msg_data($message); + $message = zmq_recvmsg($frontend); + + my $data = zmq_msg_data($message); + + my $manager = centreon::esxd::common::init_response(); + + if ($centreonesxd->{stop} != 0) { + # We quit so we say we're leaving ;) + $manager->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'Daemon is restarting...'); + centreon::esxd::common::response(endpoint => $frontend, identity => $identity); + } elsif ($data =~ /^REQCLIENT\s+(.*)$/) { + + + + zmq_sendmsg($frontend, "server-" . $1, ZMQ_SNDMORE); + zmq_sendmsg($frontend, $data); + + my $manager = centreon::esxd::common::init_response(); + $manager->{output}->output_add(severity => 'OK', + short_msg => 'ma reponse enfin'); + centreon::esxd::common::response(endpoint => $frontend, identity => $identity); + } + + my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); + last unless $more; + } +} + +sub vsphere_event { + while (1) { + # Process all parts of the message + my $message = zmq_recvmsg($backend); + print "=== " . Data::Dumper::Dumper(zmq_msg_data($message)) . " ===\n"; + + zmq_sendmsg($backend, 'bien tutu'); + + print "=PLAPLA=\n"; + my $data = zmq_msg_data($message); + if (defined($message)) { + if ($centreonesxd->{vsphere_connected}) { + $centreonesxd->{logger}->writeLogInfo("vpshere '" . $centreonesxd->{whoaim} . "' handler asking: $message"); + + $centreonesxd->{child_proc}->{pid} = fork; + if (!$centreonesxd->{child_proc}->{pid}) { + # Child + $centreonesxd->{logger}->{log_mode} = 1 if ($centreonesxd->{logger}->{log_mode} == 0); + my ($id, $name, @args) = split /\Q$centreonesxd->{separatorin}\E/, $message; + $centreonesxd->{global_id} = $id; + $centreonesxd->{modules_registry}->{$name}->initArgs(@args); + $centreonesxd->{modules_registry}->{$name}->run(); + exit(0); + } + } else { + #print $handle_writer_pipe "$id|-1|Vsphere connection error.\n"; + } + } + + my $more = zmq_getsockopt($backend, ZMQ_RCVMORE); + #zmq_sendmsg($backend, $message, $more ? ZMQ_SNDMORE : 0); + last unless $more; + } +} + sub vsphere_handler { - my $self = shift; + $centreonesxd = shift; my $timeout_process; my $context = zmq_init(); - my $backend = zmq_socket($context, ZMQ_DEALER); - #zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $self->{whoaim}); - #zmq_connect($backend, 'ipc://routing.ipc'); + $backend = zmq_socket($context, ZMQ_DEALER); + zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $centreonesxd->{whoaim}); + zmq_connect($backend, 'ipc://routing.ipc'); #zmq_sendmsg($backend, 'ready'); - + + # Initialize poll set + my @poll = ( + { + socket => $backend, + events => ZMQ_POLLIN, + callback => \&vsphere_event, + }, + ); + while (1) { - my $progress = $self->verify_child(); + my $progress = $centreonesxd->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}); + if ($centreonesxd->{stop} && $timeout_process > $centreonesxd->{centreonesxd_config}->{timeout_kill}) { + $centreonesxd->{logger}->writeLogError("'" . $centreonesxd->{whoaim} . "' Kill child not gently."); + foreach (keys %{$centreonesxd->{child_proc}}) { + kill('INT', $centreonesxd->{child_proc}->{$_}->{pid}); } $progress = 0; } - if ($self->{stop} && !$progress) { - if ($self->{vsphere_connected}) { + if ($centreonesxd->{stop} && !$progress) { + if ($centreonesxd->{vsphere_connected}) { eval { - $self->{session1}->logout(); + $centreonesxd->{session1}->logout(); }; } exit (0); @@ -321,28 +408,29 @@ sub vsphere_handler { ### # 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; + if (defined($centreonesxd->{last_time_vsphere}) && defined($centreonesxd->{last_time_check}) + && $centreonesxd->{last_time_vsphere} < $centreonesxd->{last_time_check}) { + $centreonesxd->{logger}->writeLogError("'" . $centreonesxd->{whoaim} . "' Disconnect"); + $centreonesxd->{vsphere_connected} = 0; eval { - $self->{session1}->logout(); + $centreonesxd->{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"); + if ($centreonesxd->{vsphere_connected} == 0) { + if (!centreon::esxd::common::connect_vsphere($centreonesxd->{logger}, + $centreonesxd->{whoaim}, + $centreonesxd->{centreonesxd_config}->{timeout_vsphere}, + \$centreonesxd->{session1}, + $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$centreonesxd->{whoaim}}->{url}, + $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$centreonesxd->{whoaim}}->{username}, + $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$centreonesxd->{whoaim}}->{password})) { + $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Vsphere connection ok"); + $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Create perf counters cache in progress"); + if (!centreon::esxd::common::cache_perf_counters($centreonesxd)) { + $centreonesxd->{last_time_vsphere} = time(); + $centreonesxd->{keeper_session_time} = time(); + $centreonesxd->{vsphere_connected} = 1; + $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Create perf counters cache done"); } } } @@ -350,136 +438,109 @@ sub vsphere_handler { ### # Manage session time ### - if (defined($self->{keeper_session_time}) && (time() - $self->{keeper_session_time}) > ($self->{centreonesxd_config}->{refresh_keeper_session} * 60)) { + if (defined($centreonesxd->{keeper_session_time}) && + (time() - $centreonesxd->{keeper_session_time}) > ($centreonesxd->{centreonesxd_config}->{refresh_keeper_session} * 60)) { my $stime; eval { - $stime = $self->{session1}->get_service_instance()->CurrentTime(); - $self->{keeper_session_time} = time(); + $stime = $centreonesxd->{session1}->get_service_instance()->CurrentTime(); + $centreonesxd->{keeper_session_time} = time(); }; if ($@) { - $self->{logger}->writeLogError("$@"); - $self->{logger}->writeLogError("'" . $self->{whoaim} . "' Ask a new connection"); + $centreonesxd->{logger}->writeLogError("$@"); + $centreonesxd->{logger}->writeLogError("'" . $centreonesxd->{whoaim} . "' Ask a new connection"); # Ask a new connection - $self->{last_time_check} = time(); + $centreonesxd->{last_time_check} = time(); } else { - $self->{logger}->writeLogInfo("'" . $self->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); + $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); } } my $data_element; my @rh_set; - if ($self->{vsphere_connected} == 0) { + if ($centreonesxd->{vsphere_connected} == 0) { sleep(5); } - if ($self->{stop} != 0) { + if ($centreonesxd->{stop} != 0) { sleep(1); next; } - my $message = zmq_recvmsg($backend, ZMQ_DONTWAIT); - if (defined($message)) { - if ($self->{vsphere_connected}) { - $self->{logger}->writeLogInfo("vpshere '" . $self->{whoaim} . "' handler asking: $message"); - - $self->{child_proc}->{pid} = fork; - if (!$self->{child_proc}->{pid}) { - # Child - $self->{logger}->{log_mode} = 1 if ($self->{logger}->{log_mode} == 0); - my ($id, $name, @args) = split /\Q$self->{separatorin}\E/, $data_element; - $self->{global_id} = $id; - $self->{modules_registry}->{$name}->initArgs(@args); - $self->{modules_registry}->{$name}->run(); - exit(0); - } - } else { - #print $handle_writer_pipe "$id|-1|Vsphere connection error.\n"; - } - } + print "====chaton===\n"; + zmq_poll(\@poll, 5000); } } sub create_vsphere_child { my ($self, %options) = @_; - + + $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 0; $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); $self->{whoaim} = $options{vsphere_name}; - $self->{child_vpshere_pid} = fork(); - if (!$self->{child_vpshere_pid}) { + my $child_vpshere_pid = fork(); + if ($child_vpshere_pid == 0) { $self->vsphere_handler(); exit(0); } + $self->{childs_vpshere_pid}->{$child_vpshere_pid} = $self->{whoaim}; $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 1; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{child_vpshere_pid}} = { name => $self->{whoaim} }; } sub run { - my $self = shift; + $centreonesxd = shift; - $self->SUPER::run(); - $self->{logger}->redirect_output(); + $centreonesxd->SUPER::run(); + $centreonesxd->{logger}->redirect_output(); - $self->{logger}->writeLogDebug("centreonesxd launched...."); - $self->{logger}->writeLogDebug("PID: $$"); + $centreonesxd->{logger}->writeLogDebug("centreonesxd launched...."); + $centreonesxd->{logger}->writeLogDebug("PID: $$"); my $context = zmq_init(); - my $frontend = zmq_socket($context, ZMQ_ROUTER); + $frontend = zmq_socket($context, ZMQ_ROUTER); zmq_bind($frontend, 'tcp://*:5700'); zmq_bind($frontend, 'ipc://routing.ipc'); if (!defined($frontend)) { - $self->{logger}->writeLogError("Can't setup server: $!"); + $centreonesxd->{logger}->writeLogError("Can't setup server: $!"); exit(1); } - foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { - $self->create_vsphere_child(vsphere_name => $_); + foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { + $centreonesxd->create_vsphere_child(vsphere_name => $_); } - $self->{logger}->writeLogInfo("[Server accepting clients]"); + $centreonesxd->{logger}->writeLogInfo("[Server accepting clients]"); # Initialize poll set my @poll = ( { socket => $frontend, events => ZMQ_POLLIN, - callback => sub { - while (1) { - # Process all parts of the message - my $message = zmq_recvmsg($frontend); - print "=== " . Data::Dumper::Dumper(zmq_msg_data($message)) . " ===\n"; - $message = zmq_recvmsg($frontend); - print "=== " . Data::Dumper::Dumper(zmq_msg_data($message)) . " ===\n"; - - my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); - - #zmq_sendmsg($backend, $message, $more ? ZMQ_SNDMORE : 0); - last unless $more; - return 1; - } - } + callback => \&router_event, }, ); # Switch messages between sockets while (1) { - #if ($self->{stop} == 1) { + my $count = $centreonesxd->verify_child_vsphere(); + + if ($centreonesxd->{stop} == 1) { # No childs - # if (scalar(keys %{$self->{centreonesxd_config}->{vsphere_server}}) == 0) { - # $self->{logger}->writeLogInfo("Quit main process"); - # exit(0); - # } - # foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { - # $self->{logger}->writeLogInfo("Send STOP command to '$_' child."); - # my $send_msg = zmq_msg_init_data($_ . " STOP"); - # zmq_msg_send($send_msg, $publisher, 0); - # } - # $self->{stop} = 2; - #} + if ($count == 0) { + $centreonesxd->{logger}->writeLogInfo("Quit main process"); + exit(0); + } + foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { + $centreonesxd->{logger}->writeLogInfo("Send STOP command to '$_' child."); + zmq_sendmsg($frontend, "server-" . $_, ZMQ_SNDMORE); + zmq_sendmsg($frontend, "STOP"); + } + $centreonesxd->{stop} = 2; + } - zmq_poll(\@poll, 1000); + zmq_poll(\@poll, 5000); } } From 92db819eae203c5c5f9cdfee502415373ac4d844 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 20 Oct 2014 17:24:58 +0200 Subject: [PATCH 090/447] Refs #7246 WIP --- .../vmware/src/centreon/esxd/cmdhealthhost.pm | 104 +++--- connectors/vmware/src/centreon/esxd/common.pm | 101 ++---- .../vmware/src/centreon/esxd/connector.pm | 299 ++++++++++++++++++ .../src/centreon/script/centreonesxd.pm | 277 +++++----------- 4 files changed, 452 insertions(+), 329 deletions(-) create mode 100644 connectors/vmware/src/centreon/esxd/connector.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm index 26a1cfc40..fcf0a2b7d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'healthhost'; bless $self, $class; @@ -22,26 +21,38 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($host) = @_; + my ($self, %options) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (!defined($options{arguments}->{esx_hostname}) || $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: need esx hostname"); return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{storage_status} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = ('name' => $self->{lhost}); + my %filters = (name => $self->{esx_hostname}); my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); @@ -49,20 +60,13 @@ sub run { return ; } - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{esx_hostname}, $$result[0]->{'runtime.connectionState'}->val) == 0); - my $status = 0; # OK - my $output_critical = ''; - my $output_critical_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output = ''; - my $output_append = ''; - my $OKCount = 0; - my $CAlertCount = 0; - my $WAlertCount = 0; foreach my $entity_view (@$result) { + my $OKCount = 0; + my $CAlertCount = 0; + my $WAlertCount = 0; my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{cpuStatusInfo}; my $memoryStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{memoryStatusInfo}; my $storageStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{storageStatusInfo}; @@ -72,14 +76,10 @@ sub run { if (defined($cpuStatusInfo)) { foreach (@$cpuStatusInfo) { if ($_->status->key =~ /^red$/i) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); $CAlertCount++; } elsif ($_->status->key =~ /^yellow$/i) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); $WAlertCount++; } else { $OKCount++; @@ -91,14 +91,10 @@ sub run { if (defined($memoryStatusInfo)) { foreach (@$memoryStatusInfo) { if ($_->status->key =~ /^red$/i) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); $CAlertCount++; } elsif ($_->status->key =~ /^yellow$/i) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); $WAlertCount++; } else { $OKCount++; @@ -110,14 +106,10 @@ sub run { if ($self->{storage_status} == 1 && defined($storageStatusInfo)) { foreach (@$storageStatusInfo) { if ($_->status->key =~ /^red$/i) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); $CAlertCount++; } elsif ($_->status->key =~ /^yellow$/i) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - $_->name . ": " . $_->status->summary); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); $WAlertCount++; } else { $OKCount++; @@ -129,34 +121,32 @@ sub run { if (defined($numericSensorInfo)) { foreach (@$numericSensorInfo) { if ($_->healthState->key =~ /^red$/i) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $self->{manager}->{output}->output_add(long_msg => $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); $CAlertCount++; } elsif ($_->healthState->key =~ /^yellow$/i) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $self->{manager}->{output}->output_add(long_msg => $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); $WAlertCount++; } else { $OKCount++; } } } + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $WAlertCount, + threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s health issue(s) found", $WAlertCount)); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $CAlertCount, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' } ]); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s health issue(s) found", $CAlertCount)); + } + + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %s health checks are green", $OKCount)); } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $CAlertCount health issue(s) found: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $WAlertCount health issue(s) found: $output_warning"; - } - if ($status == 0) { - $output = "All $OKCount health checks are green"; - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 147cb3f3d..9036dda32 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -14,10 +14,6 @@ use centreon::plugins::perfdata; my $manager_display = {}; -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 init_response { $manager_display->{options} = centreon::plugins::options->new(); $manager_display->{output} = centreon::plugins::output->new(options => $manager_display->{options}); @@ -30,64 +26,37 @@ sub response { my (%options) = @_; my $stdout; - { + if (!defined($options{stdout})) { local *STDOUT; $manager_display->{output}->{option_results}->{output_json} = 1; open STDOUT, '>', \$stdout; - $manager_display->{output}->display(force_long_output => 1); + $manager_display->{output}->display(force_long_output => 1, nolabel => 1); + } else { + $stdout = $options{stdout}; } - print "====stdout === $stdout===\n"; - zmq_sendmsg($options{endpoint}, $options{identity}, ZMQ_SNDMORE); - zmq_sendmsg($options{endpoint}, "RESPSERVER " . $stdout); -} - -sub errors_mask { - my ($status, $state) = @_; - - $status |= $MYERRORS_MASK{$state}; - return $status; -} - -sub get_status { - my ($state) = @_; - - return $ERRORS{$MYERRORS{$state}}; -} - -sub response_client2 { - my ($obj_esxd, $id, $msg) = @_; - - # Avoid croak kill. Can be happened (not often) - eval { - ${$obj_esxd->{sockets}->{$id}->{obj}}->send($msg); - }; - $obj_esxd->{read_select}->remove(${$obj_esxd->{sockets}->{$id}->{obj}}); - close ${$obj_esxd->{sockets}->{$id}->{obj}}; - delete $obj_esxd->{sockets}->{$id}; -} - -sub response_client1 { - my ($obj_esxd, $rh, $current_fileno, $msg) = @_; - - # Avoid croak kill. Can be happened (not often) - eval { - $rh->send($msg); - }; - $obj_esxd->{read_select}->remove($rh); - close $rh; - delete $obj_esxd->{sockets}->{$current_fileno}; + if (defined($options{reinit})) { + my $context = zmq_init(); + $options{endpoint} = zmq_socket($context, ZMQ_DEALER); + zmq_connect($options{endpoint}, $options{reinit}); + } + if (defined($options{identity})) { + zmq_sendmsg($options{endpoint}, $options{identity}, ZMQ_SNDMORE); + } + zmq_sendmsg($options{endpoint}, $options{token} . " " . $stdout); } sub vmware_error { my ($obj_esxd, $lerror) = @_; + $manager_display->{output}->output_add(long_msg => $lerror); $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $lerror"); - $lerror =~ s/\n/ /g; if ($lerror =~ /NoPermissionFault/i) { - $obj_esxd->print_response("-2|Error: Not enough permissions\n"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'VMWare error: not enought permissions'); } else { - $obj_esxd->print_response("-1|Error: " . $lerror . "\n"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'VMWare error (verbose mode for more details)'); } return undef; } @@ -104,7 +73,7 @@ sub connect_vsphere { password => $password); alarm(0); }; - if($@) { + if ($@) { $logger->writeLogError("'$whoaim' No response from VirtualCenter server") if($@ =~ /TIMEOUT/); $logger->writeLogError("'$whoaim' You need to upgrade HTTP::Message!") if($@ =~ /HTTP::Message/); $logger->writeLogError("'$whoaim' Login to VirtualCenter server failed: $@"); @@ -120,12 +89,6 @@ sub connect_vsphere { 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)); @@ -252,7 +215,8 @@ sub generic_performance_values_historic { my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { - $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe you have call a wrong instance.\n"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'Cannot get value for counters. Maybe you have call a wrong instance'); return undef; } foreach my $val (@$perfdata) { @@ -261,7 +225,8 @@ sub generic_performance_values_historic { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; next; } elsif (!defined($_->value)) { - $obj_esxd->print_response("-3|Error: Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also).\n"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also)'); return undef; } @@ -330,8 +295,8 @@ sub get_entities_host { } 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"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Object $view_type does not exist"); return undef; } #eval { @@ -400,15 +365,15 @@ sub vm_state { if ($connection_state !~ /^connected$/i) { my $output = "VM '" . $vm . "' not connected. Current Connection State: '$connection_state'."; - my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error}); - $obj_esxd->print_response(get_status($status) . "|$output\n"); + $manager_display->{output}->output_add(severity => $obj_esxd->{centreonesxd_config}->{vm_state_error}, + short_msg => $output); return 0; } - if (!defined($nocheck_ps) && $power_state !~ /^poweredOn$/i) { + if (!defined($nocheck_ps) && $power_state !~ /^poweredOn$/i) { my $output = "VM '" . $vm . "' not running. Current Power State: '$power_state'."; - my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{vm_state_error}); - $obj_esxd->print_response(get_status($status) . "|$output\n"); + $manager_display->{output}->output_add(severity => $obj_esxd->{centreonesxd_config}->{vm_state_error}, + short_msg => $output); return 0; } @@ -420,8 +385,8 @@ sub host_state { if ($connection_state !~ /^connected$/i) { my $output = "Host '" . $host . "' not connected. Current Connection State: '$connection_state'."; - my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{host_state_error}); - $obj_esxd->print_response(get_status($status) . "|$output\n"); + $manager_display->{output}->output_add(severity => $obj_esxd->{centreonesxd_config}->{host_state_error}, + short_msg => $output); return 0; } @@ -443,7 +408,7 @@ sub stats_info { } 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"); + #response_client1($obj_esxd, $rh, $current_fileno, get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm new file mode 100644 index 000000000..3b8fb79a6 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -0,0 +1,299 @@ +#!/usr/bin/perl -w + +package centreon::esxd::connector; + +use strict; +use VMware::VIRuntime; +use VMware::VILib; +use JSON; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use File::Basename; +use POSIX ":sys_wait_h"; +use centreon::script; +use centreon::esxd::common; + +my %handlers = (TERM => {}, HUP => {}, CHLD => {}); +my ($connector, $backend); + +sub new { + my ($class, %options) = @_; + $connector = {}; + bless $connector, $class; + + $connector->{child_proc} = {}; + $connector->{return_child} = {}; + $connector->{vsphere_connected} = 0; + $connector->{last_time_vsphere} = undef; + $connector->{keeper_session_time} = undef; + $connector->{last_time_check} = undef; + $connector->{perfmanager_view} = undef; + $connector->{perfcounter_cache} = {}; + $connector->{perfcounter_cache_reverse} = {}; + $connector->{perfcounter_refreshrate} = 20; + $connector->{perfcounter_speriod} = -1; + $connector->{stop} = 0; + $connector->{childs_vpshere_pid} = {}; + $connector->{session1} = undef; + + $connector->{modules_registry} = $options{modules_registry}; + $connector->{logger} = $options{logger}; + $connector->{whoaim} = $options{name}; + $connector->{module_date_parse_loaded} = $options{module_date_parse_loaded}; + $connector->{config_child_timeout} = $options{config}->{timeout}; + $connector->{config_stop_child_timeout} = $options{config}->{timeout_kill}; + $connector->{config_vsphere_session_heartbeat} = $options{config}->{refresh_keeper_session}; + $connector->{config_vsphere_connect_timeout} = $options{config}->{timeout_vsphere}; + $connector->{config_vsphere_url} = $options{config}->{vsphere_server}->{$options{name}}->{url}; + $connector->{config_vsphere_user} = $options{config}->{vsphere_server}->{$options{name}}->{username}; + $connector->{config_vsphere_pass} = $options{config}->{vsphere_server}->{$options{name}}->{password}; + + return $connector; +} + +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 response_router { + my ($self, %options) = @_; + + my $manager = centreon::esxd::common::init_response(); + $manager->{output}->output_add(severity => $options{severity}, + short_msg => $options{msg}); + $manager->{output}->{plugin} = $options{identity}; + centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend); +} + +sub verify_child { + my $self = shift; + my $progress = 0; + + # Verify process + foreach (keys %{$self->{child_proc}}) { + # Check ctime + if (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { + $self->response_router(severity => 'UNKNOWN', msg => 'Timeout process', + identity => $_); + kill('INT', $self->{child_proc}->{$_}->{pid}); + 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 reqclient { + my ($self, %options) = @_; + + my $result; + eval { + $result = JSON->new->utf8->decode($options{data}); + }; + if ($@) { + $self->{logger}->writeLogError("Cannot decode JSON: $@ (options{data}"); + return ; + } + + if ($self->{vsphere_connected}) { + $self->{logger}->writeLogInfo("vpshere '" . $self->{whoaim} . "' handler asking: $options{data}"); + + $self->{child_proc}->{$result->{identity}} = { ctime => time() }; + $self->{child_proc}->{$result->{identity}}->{pid} = fork; + if (!$self->{child_proc}->{$result->{identity}}->{pid}) { + $self->{modules_registry}->{$result->{command}}->set_connector(connector => $self); + $self->{modules_registry}->{$result->{command}}->initArgs(arguments => $result); + $self->{modules_registry}->{$result->{command}}->run(); + + centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc://routing.ipc'); + exit(0); + } + } else { + $self->response_router(severity => 'UNKNOWN', msg => 'Container connection problem', + identity => $result->{identity}); + } +} + +sub vsphere_event { + while (1) { + # Process all parts of the message + my $message = zmq_recvmsg($backend); + my $data = zmq_msg_data($message); + + if ($data =~ /^REQCLIENT\s+(.*)$/msi) { + $connector->reqclient(data => $1); + } + + my $more = zmq_getsockopt($backend, ZMQ_RCVMORE); + last unless $more; + } +} + +sub run { + my ($connector) = shift; + my $timeout_process = 0; + + my $context = zmq_init(); + + $backend = zmq_socket($context, ZMQ_DEALER); + zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); + zmq_connect($backend, 'ipc://routing.ipc'); + + # Initialize poll set + my @poll = ( + { + socket => $backend, + events => ZMQ_POLLIN, + callback => \&vsphere_event, + }, + ); + + while (1) { + my $progress = $connector->verify_child(); + + ##### + # Manage ending + ##### + if ($connector->{stop} && $timeout_process > $connector->{config_stop_child_timeout}) { + $connector->{logger}->writeLogError("'" . $connector->{whoaim} . "' Kill child not gently."); + foreach (keys %{$connector->{child_proc}}) { + kill('INT', $connector->{child_proc}->{$_}->{pid}); + } + $progress = 0; + } + if ($connector->{stop} && !$progress) { + if ($connector->{vsphere_connected}) { + eval { + $connector->{session1}->logout(); + }; + } + exit (0); + } + + ### + # Manage vpshere connection + ### + if (defined($connector->{last_time_vsphere}) && defined($connector->{last_time_check}) + && $connector->{last_time_vsphere} < $connector->{last_time_check}) { + $connector->{logger}->writeLogError("'" . $connector->{whoaim} . "' Disconnect"); + $connector->{vsphere_connected} = 0; + eval { + $connector->{session1}->logout(); + }; + } + + if ($connector->{vsphere_connected} == 0) { + if (!centreon::esxd::common::connect_vsphere($connector->{logger}, + $connector->{whoaim}, + $connector->{config_vsphere_connect_timeout}, + \$connector->{session1}, + $connector->{config_vsphere_url}, + $connector->{config_vsphere_user}, + $connector->{config_vsphere_pass})) { + $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Vsphere connection ok"); + $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Create perf counters cache in progress"); + if (!centreon::esxd::common::cache_perf_counters($connector)) { + $connector->{last_time_vsphere} = time(); + $connector->{keeper_session_time} = time(); + $connector->{vsphere_connected} = 1; + $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Create perf counters cache done"); + } + } + } + + ### + # Manage session time + ### + if (defined($connector->{keeper_session_time}) && + (time() - $connector->{keeper_session_time}) > ($connector->{config_vsphere_session_heartbeat} * 60)) { + my $stime; + + eval { + $stime = $connector->{session1}->get_service_instance()->CurrentTime(); + $connector->{keeper_session_time} = time(); + }; + if ($@) { + $connector->{logger}->writeLogError("$@"); + $connector->{logger}->writeLogError("'" . $connector->{whoaim} . "' Ask a new connection"); + # Ask a new connection + $connector->{last_time_check} = time(); + } else { + $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); + } + } + + my $data_element; + my @rh_set; + if ($connector->{vsphere_connected} == 0) { + sleep(5); + } + if ($connector->{stop} != 0) { + sleep(1); + $timeout_process++; + next; + } + + zmq_poll(\@poll, 5000); + } +} + +1; + +__END__ \ No newline at end of file diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index eecf6cea6..e78488bde 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -1,19 +1,22 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl package centreon::script::centreonesxd; use strict; +use warnings; use VMware::VIRuntime; use VMware::VILib; use ZMQ::LibZMQ3; use ZMQ::Constants qw(:all); use File::Basename; use POSIX ":sys_wait_h"; +use JSON; use Data::Dumper; use centreon::script; use centreon::esxd::common; +use centreon::esxd::connector; -my ($centreonesxd, $frontend, $backend); +my ($centreonesxd, $frontend); BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; @@ -22,8 +25,9 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreonesxd_config); -my $VERSION = "1.5.6"; +my $VERSION = "1.6.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); + my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', 'centreon::esxd::cmdcpuvm', @@ -87,21 +91,9 @@ sub new { } ); - $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->{childs_vpshere_pid} = {}; - $self->{session1} = undef; $self->{counter} = 0; $self->{whoaim} = undef; # to know which vsphere to connect $self->{module_date_parse_loaded} = 0; @@ -219,19 +211,13 @@ sub handle_CHLD { $SIG{CHLD} = \&class_handle_CHLD; } -sub print_response { - my $self = shift; - - print $self->{global_id} . "|" . $_[0]; -} - sub load_module { my $self = shift; for (@_) { (my $file = "$_.pm") =~ s{::}{/}g; require $file; - my $obj = $_->new($self->{logger}, $self); + my $obj = $_->new($self->{logger}); $self->{modules_registry}->{$obj->getCommandName()} = $obj; } } @@ -263,35 +249,64 @@ sub verify_child_vsphere { $count++; } } - + return $count; } -sub verify_child { - my $self = shift; - my $progress = 0; - - # Verify process - foreach (keys %{$self->{child_proc}}) { - # Check ctime - if (time() - $self->{child_proc}->{$_}->{ctime} > $self->{centreonesxd_config}->{timeout}) { - print "===timeout papa===\n"; - #print $handle_writer_pipe "$_|-1|Timeout Process.\n"; - kill('INT', $self->{child_proc}->{$_}->{pid}); - delete $self->{child_proc}->{$_}; - } else { - $progress++; - } +sub request { + my ($self, %options) = @_; + + # Decode json + my $result; + eval { + $result = JSON->new->utf8->decode($options{data}); + }; + if ($@) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Cannot decode json result: $@"); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; } - # 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}->{$_}; - } + if (!defined($self->{modules_registry}->{$result->{command}})) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Unknown method name '$result->{command}'"); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; + } + if ($self->{modules_registry}->{$result->{command}}->checkArgs(manager => $options{manager}, + arguments => $result)) { + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; + } + if (!defined($self->{centreonesxd_config}->{vsphere_server}->{$result->{container}})) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Unknown container name '$result->{container}'"); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; } - return $progress; + zmq_sendmsg($frontend, "server-" . $result->{container}, ZMQ_SNDMORE); + zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}); +} + +sub repserver { + my ($self, %options) = @_; + + # Decode json + my $result; + eval { + $result = JSON->new->utf8->decode($options{data}); + }; + if ($@) { + $self->{logger}->writeLogError("Cannot decode JSON: $@ (options{data}"); + return ; + } + + $result->{plugin}->{name} =~ /^client-(.*)$/; + my $identity = 'client-' . pack('H*', $1); + + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, + identity => $identity, stdout => $options{data}); } sub router_event { @@ -304,183 +319,37 @@ sub router_event { my $data = zmq_msg_data($message); my $manager = centreon::esxd::common::init_response(); - if ($centreonesxd->{stop} != 0) { # We quit so we say we're leaving ;) $manager->{output}->output_add(severity => 'UNKNOWN', short_msg => 'Daemon is restarting...'); - centreon::esxd::common::response(endpoint => $frontend, identity => $identity); - } elsif ($data =~ /^REQCLIENT\s+(.*)$/) { - - - - zmq_sendmsg($frontend, "server-" . $1, ZMQ_SNDMORE); - zmq_sendmsg($frontend, $data); - - my $manager = centreon::esxd::common::init_response(); - $manager->{output}->output_add(severity => 'OK', - short_msg => 'ma reponse enfin'); - centreon::esxd::common::response(endpoint => $frontend, identity => $identity); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $identity); + } elsif ($data =~ /^REQCLIENT\s+(.*)$/msi) { + $centreonesxd->request(identity => $identity, data => $1, manager => $manager); + } elsif ($data =~ /^RESPSERVER2\s+(.*)$/msi) { + $centreonesxd->repserver(data => $1, manager => $manager); } - + my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); last unless $more; } } -sub vsphere_event { - while (1) { - # Process all parts of the message - my $message = zmq_recvmsg($backend); - print "=== " . Data::Dumper::Dumper(zmq_msg_data($message)) . " ===\n"; - - zmq_sendmsg($backend, 'bien tutu'); - - print "=PLAPLA=\n"; - my $data = zmq_msg_data($message); - if (defined($message)) { - if ($centreonesxd->{vsphere_connected}) { - $centreonesxd->{logger}->writeLogInfo("vpshere '" . $centreonesxd->{whoaim} . "' handler asking: $message"); - - $centreonesxd->{child_proc}->{pid} = fork; - if (!$centreonesxd->{child_proc}->{pid}) { - # Child - $centreonesxd->{logger}->{log_mode} = 1 if ($centreonesxd->{logger}->{log_mode} == 0); - my ($id, $name, @args) = split /\Q$centreonesxd->{separatorin}\E/, $message; - $centreonesxd->{global_id} = $id; - $centreonesxd->{modules_registry}->{$name}->initArgs(@args); - $centreonesxd->{modules_registry}->{$name}->run(); - exit(0); - } - } else { - #print $handle_writer_pipe "$id|-1|Vsphere connection error.\n"; - } - } - - my $more = zmq_getsockopt($backend, ZMQ_RCVMORE); - #zmq_sendmsg($backend, $message, $more ? ZMQ_SNDMORE : 0); - last unless $more; - } -} - -sub vsphere_handler { - $centreonesxd = shift; - my $timeout_process; - - my $context = zmq_init(); - - $backend = zmq_socket($context, ZMQ_DEALER); - zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $centreonesxd->{whoaim}); - zmq_connect($backend, 'ipc://routing.ipc'); - #zmq_sendmsg($backend, 'ready'); - - # Initialize poll set - my @poll = ( - { - socket => $backend, - events => ZMQ_POLLIN, - callback => \&vsphere_event, - }, - ); - - while (1) { - my $progress = $centreonesxd->verify_child(); - - ##### - # Manage ending - ##### - if ($centreonesxd->{stop} && $timeout_process > $centreonesxd->{centreonesxd_config}->{timeout_kill}) { - $centreonesxd->{logger}->writeLogError("'" . $centreonesxd->{whoaim} . "' Kill child not gently."); - foreach (keys %{$centreonesxd->{child_proc}}) { - kill('INT', $centreonesxd->{child_proc}->{$_}->{pid}); - } - $progress = 0; - } - if ($centreonesxd->{stop} && !$progress) { - if ($centreonesxd->{vsphere_connected}) { - eval { - $centreonesxd->{session1}->logout(); - }; - } - exit (0); - } - - ### - # Manage vpshere connection - ### - if (defined($centreonesxd->{last_time_vsphere}) && defined($centreonesxd->{last_time_check}) - && $centreonesxd->{last_time_vsphere} < $centreonesxd->{last_time_check}) { - $centreonesxd->{logger}->writeLogError("'" . $centreonesxd->{whoaim} . "' Disconnect"); - $centreonesxd->{vsphere_connected} = 0; - eval { - $centreonesxd->{session1}->logout(); - }; - } - if ($centreonesxd->{vsphere_connected} == 0) { - if (!centreon::esxd::common::connect_vsphere($centreonesxd->{logger}, - $centreonesxd->{whoaim}, - $centreonesxd->{centreonesxd_config}->{timeout_vsphere}, - \$centreonesxd->{session1}, - $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$centreonesxd->{whoaim}}->{url}, - $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$centreonesxd->{whoaim}}->{username}, - $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$centreonesxd->{whoaim}}->{password})) { - $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Vsphere connection ok"); - $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Create perf counters cache in progress"); - if (!centreon::esxd::common::cache_perf_counters($centreonesxd)) { - $centreonesxd->{last_time_vsphere} = time(); - $centreonesxd->{keeper_session_time} = time(); - $centreonesxd->{vsphere_connected} = 1; - $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Create perf counters cache done"); - } - } - } - - ### - # Manage session time - ### - if (defined($centreonesxd->{keeper_session_time}) && - (time() - $centreonesxd->{keeper_session_time}) > ($centreonesxd->{centreonesxd_config}->{refresh_keeper_session} * 60)) { - my $stime; - - eval { - $stime = $centreonesxd->{session1}->get_service_instance()->CurrentTime(); - $centreonesxd->{keeper_session_time} = time(); - }; - if ($@) { - $centreonesxd->{logger}->writeLogError("$@"); - $centreonesxd->{logger}->writeLogError("'" . $centreonesxd->{whoaim} . "' Ask a new connection"); - # Ask a new connection - $centreonesxd->{last_time_check} = time(); - } else { - $centreonesxd->{logger}->writeLogInfo("'" . $centreonesxd->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); - } - } - - my $data_element; - my @rh_set; - if ($centreonesxd->{vsphere_connected} == 0) { - sleep(5); - } - if ($centreonesxd->{stop} != 0) { - sleep(1); - next; - } - - print "====chaton===\n"; - zmq_poll(\@poll, 5000); - } -} - sub create_vsphere_child { my ($self, %options) = @_; + $self->{whoaim} = $options{vsphere_name}; $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 0; $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); - $self->{whoaim} = $options{vsphere_name}; my $child_vpshere_pid = fork(); if ($child_vpshere_pid == 0) { - $self->vsphere_handler(); + my $connector = centreon::esxd::connector->new(name => $self->{whoaim}, + modules_registry => $self->{modules_registry}, + module_date_parse_loaded => $self->{module_date_parse_loaded}, + config => $self->{centreonesxd_config}, + logger => $self->{logger}); + $connector->run(); exit(0); } $self->{childs_vpshere_pid}->{$child_vpshere_pid} = $self->{whoaim}; From d5862c4495ee9ef8a209257a17b774deb125bcaa Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 20 Oct 2014 17:58:36 +0200 Subject: [PATCH 091/447] Refs #7246 WIP --- .../vmware/src/centreon/esxd/connector.pm | 12 ++++--- .../src/centreon/script/centreonesxd.pm | 33 ++++++++++--------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index 3b8fb79a6..ef3622f7f 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -20,6 +20,7 @@ sub new { my ($class, %options) = @_; $connector = {}; bless $connector, $class; + $connector->set_signal_handlers; $connector->{child_proc} = {}; $connector->{return_child} = {}; @@ -82,13 +83,13 @@ sub class_handle_CHLD { sub handle_TERM { my $self = shift; - $self->{logger}->writeLogInfo("$$ Receiving order to stop..."); + $self->{logger}->writeLogInfo("connector '" . $self->{whoaim} . "' Receiving order to stop..."); $self->{stop} = 1; } sub handle_HUP { my $self = shift; - $self->{logger}->writeLogInfo("$$ Receiving order to reload..."); + $self->{logger}->writeLogInfo("connector $$ Receiving order to reload..."); # TODO } @@ -163,6 +164,7 @@ sub reqclient { $self->{modules_registry}->{$result->{command}}->run(); centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc://routing.ipc'); + zmq_close($backend); exit(0); } } else { @@ -223,8 +225,10 @@ sub run { eval { $connector->{session1}->logout(); }; - } - exit (0); + } + + zmq_close($backend); + exit(0); } ### diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index e78488bde..4672be8bc 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -193,6 +193,11 @@ sub handle_TERM { my $self = shift; $self->{logger}->writeLogInfo("$$ Receiving order to stop..."); $self->{stop} = 1; + + foreach (keys %{$self->{childs_vpshere_pid}}) { + kill('TERM', $_); + $self->{logger}->writeLogInfo("Send -TERM signal to '" . $self->{childs_vpshere_pid}->{$_} . "' process.."); + } } sub handle_HUP { @@ -208,6 +213,7 @@ sub handle_CHLD { while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { $self->{return_child}{$child_pid} = {status => 1, rtime => time()}; } + $SIG{CHLD} = \&class_handle_CHLD; } @@ -229,20 +235,20 @@ sub verify_child_vsphere { foreach (keys %{$self->{return_child}}) { delete $self->{return_child}->{$_}; - # We need to quit - if ($self->{stop} != 0) { - my $name = $self->{childs_vpshere_pid}->{$_}; - $self->{centreonesxd_config}->{vsphere_server}->{$name}->{running} = 0; - next; - } - if (defined($self->{childs_vpshere_pid}->{$_})) { - $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' dead ???!! We relaunch it"); - $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}); + if ($self->{stop} == 0) { + $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "'???!! we relaunch it!!!"); + + $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}); + } else { + $self->{logger}->writeLogInfo("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' dead ???!!"); + $self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{running} = 0; + } + delete $self->{childs_vpshere_pid}->{$_}; } } - + my $count = 0; foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{running} == 1) { @@ -399,14 +405,9 @@ sub run { # No childs if ($count == 0) { $centreonesxd->{logger}->writeLogInfo("Quit main process"); + zmq_close($frontend); exit(0); } - foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { - $centreonesxd->{logger}->writeLogInfo("Send STOP command to '$_' child."); - zmq_sendmsg($frontend, "server-" . $_, ZMQ_SNDMORE); - zmq_sendmsg($frontend, "STOP"); - } - $centreonesxd->{stop} = 2; } zmq_poll(\@poll, 5000); From 0870631b9f1f95725b87b6f91a30e9373dbef7eb Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 21 Oct 2014 15:30:42 +0200 Subject: [PATCH 092/447] Refs #7246 WIP --- connectors/vmware/src/centreon/esxd/cmdhealthhost.pm | 6 +++--- connectors/vmware/src/centreon/esxd/common.pm | 8 ++++++-- connectors/vmware/src/centreon/esxd/connector.pm | 9 ++++++--- connectors/vmware/src/centreon/script/centreonesxd.pm | 6 ++++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm index fcf0a2b7d..5f132c61d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm @@ -23,9 +23,9 @@ sub getCommandName { sub checkArgs { my ($self, %options) = @_; - if (!defined($options{arguments}->{esx_hostname}) || $options{arguments}->{esx_hostname} eq "") { + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: need esx hostname"); + short_msg => "Argument error: esx hostname cannot be null"); return 1; } return 0; @@ -103,7 +103,7 @@ sub run { } # Storage - if ($self->{storage_status} == 1 && defined($storageStatusInfo)) { + if (defined($self->{storage_status}) && defined($storageStatusInfo)) { foreach (@$storageStatusInfo) { if ($_->status->key =~ /^red$/i) { $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 9036dda32..bee505f0f 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -13,6 +13,7 @@ use centreon::plugins::output; use centreon::plugins::perfdata; my $manager_display = {}; +my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; sub init_response { $manager_display->{options} = centreon::plugins::options->new(); @@ -39,11 +40,14 @@ sub response { my $context = zmq_init(); $options{endpoint} = zmq_socket($context, ZMQ_DEALER); zmq_connect($options{endpoint}, $options{reinit}); + # we wait 10 seconds after. If not there is a problem... so we can quit + # dialog from vsphere response to router + zmq_setsockopt($options{endpoint}, ZMQ_LINGER, 10000); } if (defined($options{identity})) { - zmq_sendmsg($options{endpoint}, $options{identity}, ZMQ_SNDMORE); + zmq_sendmsg($options{endpoint}, $options{identity}, $flag); } - zmq_sendmsg($options{endpoint}, $options{token} . " " . $stdout); + zmq_sendmsg($options{endpoint}, $options{token} . " " . $stdout, ZMQ_NOBLOCK); } sub vmware_error { diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index ef3622f7f..85456ed7c 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -34,7 +34,6 @@ sub new { $connector->{perfcounter_refreshrate} = 20; $connector->{perfcounter_speriod} = -1; $connector->{stop} = 0; - $connector->{childs_vpshere_pid} = {}; $connector->{session1} = undef; $connector->{modules_registry} = $options{modules_registry}; @@ -120,7 +119,10 @@ sub verify_child { # Verify process foreach (keys %{$self->{child_proc}}) { # Check ctime - if (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { + if (defined($self->{return_child}->{$self->{child_proc}->{$_}->{pid}})) { + delete $self->{return_child}->{$_}; + delete $self->{child_proc}->{$_}; + } elsif (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { $self->response_router(severity => 'UNKNOWN', msg => 'Timeout process', identity => $_); kill('INT', $self->{child_proc}->{$_}->{pid}); @@ -196,6 +198,7 @@ sub run { $backend = zmq_socket($context, ZMQ_DEALER); zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); + zmq_setsockopt($backend, ZMQ_LINGER, 0); # we discard zmq_connect($backend, 'ipc://routing.ipc'); # Initialize poll set @@ -209,7 +212,7 @@ sub run { while (1) { my $progress = $connector->verify_child(); - + ##### # Manage ending ##### diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 4672be8bc..d173e8dcc 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -291,8 +291,9 @@ sub request { return ; } - zmq_sendmsg($frontend, "server-" . $result->{container}, ZMQ_SNDMORE); - zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}); + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + zmq_sendmsg($frontend, "server-" . $result->{container}, $flag); + zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); } sub repserver { @@ -374,6 +375,7 @@ sub run { my $context = zmq_init(); $frontend = zmq_socket($context, ZMQ_ROUTER); + zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard zmq_bind($frontend, 'tcp://*:5700'); zmq_bind($frontend, 'ipc://routing.ipc'); From 301cdc07ae97027990355de159d39a6d8226f514 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 21 Oct 2014 16:34:43 +0200 Subject: [PATCH 093/447] Refs #7246 Begin refactoring of commands --- .../vmware/src/centreon/esxd/cmdhealthhost.pm | 41 +++++++++++++++---- connectors/vmware/src/centreon/esxd/common.pm | 14 ++++--- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm index 5f132c61d..b0d48f725 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm @@ -52,18 +52,39 @@ sub set_connector { sub run { my $self = shift; - my %filters = (name => $self->{esx_hostname}); - my @properties = ('runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', + my %filters = (); + my $multiple = 0; + + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + + my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); if (!defined($result)) { return ; } - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{esx_hostname}, - $$result[0]->{'runtime.connectionState'}->val) == 0); + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All ESX health checks are ok")); + } foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $OKCount = 0; my $CAlertCount = 0; my $WAlertCount = 0; @@ -71,6 +92,7 @@ sub run { my $memoryStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{memoryStatusInfo}; my $storageStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{storageStatusInfo}; my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; + $self->{manager}->{output}->output_add(long_msg => sprintf("Checking %s", $entity_view->{name})); # CPU if (defined($cpuStatusInfo)) { @@ -136,16 +158,19 @@ sub run { threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s health issue(s) found", $WAlertCount)); + short_msg => sprintf("'%s' %s health issue(s) found", $entity_view->{name}, $WAlertCount)); } $exit = $self->{manager}->{perfdata}->threshold_check(value => $CAlertCount, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' } ]); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s health issue(s) found", $CAlertCount)); + short_msg => sprintf("'%s' %s health issue(s) found", $entity_view->{name}, $CAlertCount)); } - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s health checks are green", $OKCount)); + $self->{manager}->{output}->output_add(long_msg => sprintf("%s health checks are green", $OKCount)); + if ($multiple == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("'%s' %s health checks are green", $entity_view->{name}, $OKCount)); + } } } diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index bee505f0f..3db0d33e5 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -385,12 +385,16 @@ sub vm_state { } sub host_state { - my ($obj_esxd, $host, $connection_state) = @_; + my (%options) = @_; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{host_state_error}; - if ($connection_state !~ /^connected$/i) { - my $output = "Host '" . $host . "' not connected. Current Connection State: '$connection_state'."; - $manager_display->{output}->output_add(severity => $obj_esxd->{centreonesxd_config}->{host_state_error}, - short_msg => $output); + if ($options{state} !~ /^connected$/i) { + my $output = "Host '" . $options{hostname} . "' not connected. Current Connection State: '$options{state}'."; + if ($options{multiple} == 0 || + !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $manager_display->{output}->output_add(severity => $status, + short_msg => $output); + } return 0; } From 03ac8daff832027b4b842d4a6b0fc52b486dbe96 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 22 Oct 2014 11:23:43 +0200 Subject: [PATCH 094/447] Refs #7246 Refactoring of 3 commands --- .../vmware/src/centreon/esxd/cmdgetmap.pm | 70 ++++++++----- .../vmware/src/centreon/esxd/cmdhealthhost.pm | 12 ++- .../src/centreon/esxd/cmdlistdatastore.pm | 65 ------------- .../src/centreon/esxd/cmdlistdatastores.pm | 97 +++++++++++++++++++ .../vmware/src/centreon/esxd/cmdlisthost.pm | 54 ----------- .../src/centreon/esxd/cmdlistnichost.pm | 93 +++++++++++------- .../src/centreon/esxd/cmdmaintenancehost.pm | 90 ++++++++++++----- .../src/centreon/script/centreonesxd.pm | 3 +- 8 files changed, 274 insertions(+), 210 deletions(-) delete mode 100644 connectors/vmware/src/centreon/esxd/cmdlistdatastore.pm create mode 100644 connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm delete mode 100644 connectors/vmware/src/centreon/esxd/cmdlisthost.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdgetmap.pm b/connectors/vmware/src/centreon/esxd/cmdgetmap.pm index ee83bdcfb..1c06df0b9 100644 --- a/connectors/vmware/src/centreon/esxd/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/esxd/cmdgetmap.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'getmap'; bless $self, $class; @@ -22,56 +21,75 @@ sub getCommandName { } sub checkArgs { - my $self = shift; + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; my %filters = (); - if (defined($self->{lhost}) and $self->{lhost} ne "") { - %filters = ('name' => $self->{lhost}); + + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'vm'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - my $output_append = ""; + return if (!defined($result)); + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("List ESX host(s):")); + foreach my $entity_view (@$result) { - $output .= $output_append . "ESX Host '" . $entity_view->name . "': "; + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s%s", $entity_view->name, + defined($self->{vm_no}) ? '' : ':')); + next if (defined($self->{vm_no})); + my @vm_array = (); if (defined $entity_view->vm) { - @vm_array = (@vm_array, @{$entity_view->vm}); + @vm_array = (@vm_array, @{$entity_view->vm}); } @properties = ('name', 'summary.runtime.powerState'); my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result2)); + + my %vms = (); + foreach my $vm (@$result2) { + $vms{$vm->name} = $vm->{'summary.runtime.powerState'}->val; } - my $output_append2 = ''; - foreach my $vm (@$result2) { - if ($vm->{'summary.runtime.powerState'}->val eq "poweredOn") { - $output .= $output_append2 . "[" . $vm->name . "]"; - $output_append2 = ', '; - } + foreach (sort keys %vms) { + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [%s]", + $_, $vms{$_})); } - $output_append = ". "; } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm index b0d48f725..8d4d8344d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm @@ -28,6 +28,12 @@ sub checkArgs { short_msg => "Argument error: esx hostname cannot be null"); return 1; } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } return 0; } @@ -56,7 +62,7 @@ sub run { my $multiple = 0; if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; } elsif (!defined($self->{esx_hostname})) { $filters{name} = qr/.*/; } else { @@ -66,9 +72,7 @@ sub run { my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatastore.pm b/connectors/vmware/src/centreon/esxd/cmdlistdatastore.pm deleted file mode 100644 index 959e9d013..000000000 --- a/connectors/vmware/src/centreon/esxd/cmdlistdatastore.pm +++ /dev/null @@ -1,65 +0,0 @@ - -package centreon::esxd::cmdlistdatastore; - -use strict; -use warnings; -use centreon::esxd::common; - -sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'listdatastore'; - - bless $self, $class; - return $self; -} - -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - -sub checkArgs { - my $self = shift; - return 0; -} - -sub initArgs { - my $self = shift; - $self->{xml} = (defined($_[0]) && $_[0] == 1) ? 1 : 0; -} - -sub run { - my $self = shift; - - my %filters = (); - my @properties = ('summary'); - - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Datastore List: '; - my $output_append = ""; - my $xml_output = ''; - foreach my $datastore (@$result) { - if ($datastore->summary->accessible) { - $output .= $output_append . "'" . $datastore->summary->name . "'"; - $output_append = ', '; - } - $xml_output .= ''; - } - $xml_output .= ''; - - if ($self->{xml} == 1) { - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$xml_output\n"); - } else { - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); - } -} - -1; diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm b/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm new file mode 100644 index 000000000..451199aa7 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm @@ -0,0 +1,97 @@ + +package centreon::esxd::cmdlistdatastores; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'listdatastores'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datastore_name}/; + } + my @properties = ('summary'); + + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + return if (!defined($result)); + + if (!defined($self->{disco_show})) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => 'List datastore(s):'); + } + foreach my $datastore (@$result) { + if (defined($self->{disco_show})) { + $self->{manager}->{output}->add_disco_entry(name => $datastore->summary->name, + accessible => $datastore->summary->accessible); + } else { + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [%s]", + $datastore->summary->name, + $datastore->summary->accessible)); + } + } + + if (defined($self->{disco_show})) { + my $stdout; + { + local *STDOUT; + $self->{manager}->{output}->{option_results}->{output_xml} = 1; + open STDOUT, '>', \$stdout; + $self->{manager}->{output}->display_disco_show(); + delete $self->{manager}->{output}->{option_results}->{output_xml}; + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => $stdout); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/esxd/cmdlisthost.pm b/connectors/vmware/src/centreon/esxd/cmdlisthost.pm deleted file mode 100644 index 4d44ea733..000000000 --- a/connectors/vmware/src/centreon/esxd/cmdlisthost.pm +++ /dev/null @@ -1,54 +0,0 @@ - -package centreon::esxd::cmdlisthost; - -use strict; -use warnings; -use centreon::esxd::common; - -sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'listhost'; - - bless $self, $class; - return $self; -} - -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - -sub checkArgs { - my $self = shift; - return 0; -} - -sub initArgs { - my $self = shift; -} - -sub run { - my $self = shift; - my %filters = (); - my @properties = ('name'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = 'Host List: '; - my $output_append = ""; - - foreach my $entity_view (@$result) { - $output .= $output_append . $entity_view->{name}; - $output_append = ', '; - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); -} - -1; diff --git a/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm b/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm index f41269b80..72d413065 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'listnichost'; bless $self, $class; @@ -22,32 +21,40 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($host) = @_; + my ($self, %options) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (!defined($options{arguments}->{esx_hostname}) || $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname need to be set"); return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{xml} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; my %nic_in_vswitch = (); - my %filters = ('name' => $self->{lhost}); + my %filters = (name => $self->{esx_hostname}); my @properties = ('config.network.pnic', 'config.network.vswitch', 'config.network.proxySwitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); # Get Name from vswitch if (defined($$result[0]->{'config.network.vswitch'})) { @@ -68,36 +75,48 @@ sub run { } } - my $status = 0; # OK - my $output_up = 'Nic Up List: '; - my $output_down = 'Nic Down List: '; - my $output_down_no_vswitch = 'Nic Down List (not in vswitch, dvswitch): '; - my $output_up_append = ""; - my $output_down_append = ""; - my $output_down_no_vswitch_append = ""; - my $xml_output = ''; + if (!defined($self->{disco_show})) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => 'List nic host:'); + } + + my %nics = (); foreach (@{$$result[0]->{'config.network.pnic'}}) { + if (defined($nic_in_vswitch{$_->key})) { + $nics{$_->device}{vswitch} = 1; + } if (defined($_->linkSpeed)) { - $output_up .= $output_up_append . "'" . $_->device . "'"; - $output_up_append = ', '; - $xml_output .= ''; + $nics{$_->device}{up} = 1; } else { - if (defined($nic_in_vswitch{$_->key})) { - $output_down .= $output_down_append . "'" . $_->device . "'"; - $output_down_append = ', '; - $xml_output .= ''; - } else { - $output_down_no_vswitch .= $output_down_no_vswitch_append . "'" . $_->device . "'"; - $output_down_no_vswitch_append = ', '; - } + $nics{$_->device}{down} = 1; } } - $xml_output .= ''; - - if ($self->{xml} == 1) { - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$xml_output\n"); - } else { - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output_up. $output_down. $output_down_no_vswitch.\n"); + + foreach my $nic_name (sort keys %nics) { + my $status = defined($nics{$nic_name}{up}) ? 'up' : 'down'; + my $vswitch = defined($nics{$nic_name}{vswitch}) ? 1 : 0; + + if (defined($self->{disco_show})) { + $self->{manager}->{output}->add_disco_entry(name => $nic_name, + status => $status, + vswitch => $vswitch); + } else { + $self->{manager}->{output}->output_add(long_msg => sprintf('%s [status: %s] [vswitch: %s]', + $nic_name, $status, $vswitch)); + } + } + + if (defined($self->{disco_show})) { + my $stdout; + { + local *STDOUT; + $self->{manager}->{output}->{option_results}->{output_xml} = 1; + open STDOUT, '>', \$stdout; + $self->{manager}->{output}->display_disco_show(); + delete $self->{manager}->{output}->{option_results}->{output_xml}; + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => $stdout); + } } } diff --git a/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm index 8abb4bdcb..808b727c4 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'maintenancehost'; bless $self, $class; @@ -22,44 +21,91 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($lhost) = @_; + my ($self, %options) = @_; - if (!defined($lhost) || $lhost eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + if (defined($options{arguments}->{maintenance_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{maintenance_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for maintenance status '" . $options{arguments}->{maintenance_status} . "'"); return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = ('name' => $self->{lhost}); - my @properties = ('runtime.inMaintenanceMode'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + my %filters = (); + my $multiple = 0; - my $status = 0; # OK - my $output = ''; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + + my @properties = ('name', 'runtime.inMaintenanceMode', 'runtime.connectionState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All ESX maintenance mode are ok")); + } foreach my $entity_view (@$result) { - if ($entity_view->{'runtime.inMaintenanceMode'} ne "false") { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $output = "Server " . $self->{lhost} . " is on maintenance mode."; - } else { - $output = "Server " . $self->{lhost} . " is not on maintenance mode."; + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' maintenance mode is %s", + $entity_view->{name}, $entity_view->{'runtime.inMaintenanceMode'})); + + if ($entity_view->{'runtime.inMaintenanceMode'} =~ /$self->{maintenance_alert}/ && + !$self->{manager}->{output}->is_status(value => $self->{maintenance_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{maintenance_status}, + short_msg => sprintf("'%s' maintenance mode is %s", + $entity_view->{name}, $entity_view->{'runtime.inMaintenanceMode'})) + } elsif ($multiple == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("'%s' maintenance mode is %s", + $entity_view->{name}, $entity_view->{'runtime.inMaintenanceMode'})) } } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index d173e8dcc..329e5a85e 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -40,8 +40,7 @@ my @load_modules = ('centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdgetmap', 'centreon::esxd::cmdhealthhost', 'centreon::esxd::cmdlimitvm', - 'centreon::esxd::cmdlistdatastore', - 'centreon::esxd::cmdlisthost', + 'centreon::esxd::cmdlistdatastores', 'centreon::esxd::cmdlistnichost', 'centreon::esxd::cmdmemhost', 'centreon::esxd::cmdmaintenancehost', From bfb15e4d9372ecc91250019c6fc1f3b6db6ce152 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 22 Oct 2014 14:57:15 +0200 Subject: [PATCH 095/447] Refs #7246 First command with perfdata --- connectors/vmware/centreon_esx_client.pl | 27 +--- .../vmware/src/centreon/esxd/cmdcpuhost.pm | 147 ++++++++++++------ .../vmware/src/centreon/esxd/cmdstatushost.pm | 98 +++++++----- connectors/vmware/src/centreon/esxd/common.pm | 43 ++--- .../vmware/src/centreon/esxd/connector.pm | 4 +- .../src/centreon/script/centreonesxd.pm | 10 +- 6 files changed, 196 insertions(+), 133 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index dc76dca10..ef1646a95 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -113,16 +113,7 @@ sub print_usage () { print " --vsphere vsphere name (default: none)\n"; print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; - print "'healthhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --storage-status Check storage of ESX\n"; - print "\n"; - print "'maintenancehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'statushost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; + print "'datastore-usage':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold (default 80)\n"; @@ -248,21 +239,7 @@ sub print_usage () { print " --warn Warn\n"; print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; print "\n"; - print "'listhost':\n"; - print " None\n"; - print "\n"; - print "'listdatastore':\n"; - print " --xml centreon-autodiscovery xml format\n"; - print " --show-attributes centreon-autodiscovery attributes xml display\n"; - print "\n"; - print "'listnichost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --xml centreon-autodiscovery xml format\n"; - print " --show-attributes centreon-autodiscovery attributes xml display\n"; - print "\n"; - print "'getmap':\n"; - print " -e (--esx-host) Esx Host to check\n"; - print "\n"; + print "'stats':\n"; print " -w (--warning) Warning Threshold in total client connections (default none)\n"; print " -c (--critical) Critical Threshold in total client connections (default none)\n"; diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm index dca0a7241..a4907fa6e 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'cpuhost'; bless $self, $class; @@ -21,86 +20,132 @@ sub getCommandName { return $self->{commandName}; } -sub checkArgs { - my $self = shift; - my ($host, $warn, $crit, $light_perfdata) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 80); - $self->{crit} = (defined($_[2]) ? $_[2] : 90); - $self->{light_perfdata} = (defined($_[3]) ? $_[3] : 0); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lhost}); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); return if (!defined($result)); - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - + if (scalar(@$result) > 1) { + $multiple = 1; + } my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $result, - [{'label' => 'cpu.usage.average', 'instances' => \@instances}], - $self->{obj_esxd}->{perfcounter_speriod}); + $result, + [{'label' => 'cpu.usage.average', 'instances' => \@instances}], + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $status = 0; # OK - my $output = ''; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - - if ($total_cpu_average >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if ($total_cpu_average >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } - $output = "Total Average CPU usage '$total_cpu_average%' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100"; + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Total Average CPU usages are ok")); + } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", + $entity_view->{name}, $total_cpu_average, int($self->{obj_esxd}->{perfcounter_speriod} / 60))); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", + $entity_view->{name}, $total_cpu_average, int($self->{obj_esxd}->{perfcounter_speriod} / 60))); + } - foreach my $id (sort { my ($cida, $cia) = split /:/, $a; - my ($cidb, $cib) = split /:/, $b; - $cia = -1 if (!defined($cia) || $cia eq ""); - $cib = -1 if (!defined($cib) || $cib eq ""); - $cia <=> $cib} keys %$values) { - my ($counter_id, $instance) = split /:/, $id; - if ($instance ne "" and $self->{light_perfdata} != 1) { - $output .= " cpu$instance=" . centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'cpu_total' . $extra_label, unit => '%', + value => $total_cpu_average, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %{$values->{$entity_value}}) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "") { + $self->{manager}->{output}->perfdata_add(label => 'cpu' . $instance . $extra_label, unit => '%', + value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0]) * 0.01), + min => 0, max => 100); + } } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm index 7757110c9..021b2bff6 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'statushost'; bless $self, $class; @@ -22,63 +21,92 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($host) = @_; + my ($self, %options) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = ('name' => $self->{lhost}); - my @properties = ('summary.overallStatus', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + my %filters = (); + my $multiple = 0; - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - - my $status = 0; # OK - my $output = ''; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + return if (!defined($result)); + if (scalar(@$result) > 1) { + $multiple = 1; + } my %overallStatus = ( - 'gray' => 'status is unknown', - 'green' => 'is OK', - 'red' => 'has a problem', - 'yellow' => 'might have a problem', + 'gray' => 'status is unknown', + 'green' => 'is OK', + 'red' => 'has a problem', + 'yellow' => 'might have a problem', ); my %overallStatusReturn = ( - 'gray' => 'UNKNOWN', - 'green' => 'OK', - 'red' => 'CRITICAL', - 'yellow' => 'WARNING' + 'gray' => 'UNKNOWN', + 'green' => 'OK', + 'red' => 'CRITICAL', + 'yellow' => 'WARNING' ); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All ESX are ok")); + } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $status_esx = $entity_view->{'summary.overallStatus'}->val; - - if (defined($status) && $overallStatus{$status_esx}) { - $output = "The Server '" . $self->{lhost} . "' " . $overallStatus{$status_esx}; - $status = centreon::esxd::common::errors_mask($status, $overallStatusReturn{$status_esx}); - } else { - $output = "Can't interpret data..."; - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); + + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $overallStatusReturn{$status_esx}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $overallStatusReturn{$status_esx}, + short_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); } } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 3db0d33e5..afd589270 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -171,7 +171,8 @@ sub get_perf_metric_ids { } } else { $obj_esxd->{logger}->writeLogError("Metric '" . $_->{'label'} . "' unavailable."); - $obj_esxd->print_response("-3|Error: Counter doesn't exist. VMware version can be too old.\n"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Counter doesn't exist. VMware version can be too old."); return undef; } } @@ -179,7 +180,7 @@ sub get_perf_metric_ids { } sub generic_performance_values_historic { - my ($obj_esxd, $views, $perfs, $interval, $skip_undef_counter, $multiples) = @_; + my ($obj_esxd, $views, $perfs, $interval, %options) = @_; my $counter = 0; my %results; @@ -225,7 +226,7 @@ sub generic_performance_values_historic { } foreach my $val (@$perfdata) { foreach (@{$val->{value}}) { - if (defined($skip_undef_counter) && $skip_undef_counter == 1 && !defined($_->value)) { + if (defined($options{skip_undef_counter}) && $options{skip_undef_counter} == 1 && !defined($_->value)) { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; next; } elsif (!defined($_->value)) { @@ -234,8 +235,13 @@ sub generic_performance_values_historic { return undef; } - if (defined($multiples) && $multiples == 1) { - $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + if (defined($options{multiples}) && $options{multiples} == 1) { + if (defined($options{multiples_result_by_entity}) && $options{multiples_result_by_entity} == 1) { + $results{$val->{entity}->{value}} = {} if (!defined($results{$val->{entity}->{value}})); + $results{$val->{entity}->{value}}->{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + } else { + $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + } } else { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; } @@ -402,21 +408,20 @@ sub host_state { } sub stats_info { - my ($obj_esxd, $rh, $current_fileno, $args) = @_; - my $output; - my $status = 0; - - $$args[0] ='' if (!defined($$args[0])); - $$args[1] = '' if (!defined($$args[1])); - - my $num_connection = scalar(keys(%{$obj_esxd->{sockets}})); - $output = "'$num_connection' total client connections | connection=$num_connection;$$args[0];$$args[1];0; requests=" . $obj_esxd->{counter}; - if ($$args[1] ne '' and $num_connection >= $$args[1]) { - $status = errors_mask($status, 'CRITICAL'); - } elsif ($$args[0] ne '' and $num_connection >= $$args[0]) { - $status = errors_mask($status, 'WARNING'); + my (%options) = @_; + + my $total = 0; + foreach my $container (keys %{$options{counters}}) { + $total += $options{counters}->{$container}; + $options{manager}->{output}->perfdata_add(label => 'c[requests_' . $container . ']', + value => $options{counters}->{$container}, + min => 0); } - #response_client1($obj_esxd, $rh, $current_fileno, get_status($status) . "|$output\n"); + $options{manager}->{output}->perfdata_add(label => 'c[requests]', + value => $total, + min => 0); + $options{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("'%s' total requests", $total)); } 1; diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index 85456ed7c..d429ef04b 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -97,7 +97,7 @@ sub handle_CHLD { my $child_pid; while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { - $self->{return_child}{$child_pid} = {status => 1, rtime => time()}; + $self->{return_child}->{$child_pid} = {status => 1, rtime => time()}; } $SIG{CHLD} = \&class_handle_CHLD; } @@ -120,7 +120,7 @@ sub verify_child { foreach (keys %{$self->{child_proc}}) { # Check ctime if (defined($self->{return_child}->{$self->{child_proc}->{$_}->{pid}})) { - delete $self->{return_child}->{$_}; + delete $self->{return_child}->{$self->{child_proc}->{$_}->{pid}}; delete $self->{child_proc}->{$_}; } elsif (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { $self->response_router(severity => 'UNKNOWN', msg => 'Timeout process', diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 329e5a85e..491e61759 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -93,7 +93,7 @@ sub new { $self->{return_child} = {}; $self->{stop} = 0; $self->{childs_vpshere_pid} = {}; - $self->{counter} = 0; + $self->{counter_stats} = {}; $self->{whoaim} = undef; # to know which vsphere to connect $self->{module_date_parse_loaded} = 0; $self->{modules_registry} = {}; @@ -272,6 +272,12 @@ sub request { centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } + if ($result->{command} eq 'stats') { + centreon::esxd::common::stats_info(manager => $options{manager}, + counters => $self->{counter_stats}); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; + } if (!defined($self->{modules_registry}->{$result->{command}})) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Unknown method name '$result->{command}'"); @@ -290,6 +296,7 @@ sub request { return ; } + $self->{counter_stats}->{$result->{container}}++; my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; zmq_sendmsg($frontend, "server-" . $result->{container}, $flag); zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); @@ -384,6 +391,7 @@ sub run { } foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { + $centreonesxd->{counter_stats}->{$_} = 0; $centreonesxd->create_vsphere_child(vsphere_name => $_); } From ab4985ed690f0fc7f04edddb85358e87a89f4b52 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 22 Oct 2014 16:07:03 +0200 Subject: [PATCH 096/447] + Refs #7246 WIP: need commands (memhost, swaphost, uptimehost) --- connectors/vmware/centreon_esx_client.pl | 24 --- .../vmware/src/centreon/esxd/cmdmemhost.pm | 142 ++++++++++++------ .../vmware/src/centreon/esxd/cmdswaphost.pm | 134 ++++++++++++----- .../vmware/src/centreon/esxd/cmduptimehost.pm | 119 +++++++++++---- 4 files changed, 281 insertions(+), 138 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index ef1646a95..a7b0d812f 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -113,7 +113,6 @@ sub print_usage () { print " --vsphere vsphere name (default: none)\n"; print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; - print "'datastore-usage':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold (default 80)\n"; @@ -145,12 +144,6 @@ sub print_usage () { print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print " --skip-errors Status OK if not enough permissions or others errors (when you checks multiples)\n"; print "\n"; - print "'cpuhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print " --light-perfdata Display only total average cpu perfdata\n"; - print "\n"; print "'nethost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; print " --nic Physical nic name to check (required)\n"; @@ -159,16 +152,6 @@ sub print_usage () { print " --filter Use regexp for --nic option (can check multiple nics at once)\n"; print " --skip-errors Status OK if some nic are down (when you checks multiples)\n"; print "\n"; - print "'memhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print "\n"; - print "'swaphost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; print "'datastoreshost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; @@ -183,9 +166,6 @@ sub print_usage () { print " --warning2 Warning Threshold if more VMs not on (default none)\n"; print " --critical2 Critical Threshold if more VMs not on (default none)\n"; print "\n"; - print "'uptimehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; print "'cpuvm':\n"; print " --vm VM to check (required)\n"; print " -w (--warning) Warning Threshold in percent for cpu average (default 80)\n"; @@ -239,10 +219,6 @@ sub print_usage () { print " --warn Warn\n"; print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; print "\n"; - - print "'stats':\n"; - print " -w (--warning) Warning Threshold in total client connections (default none)\n"; - print " -c (--critical) Critical Threshold in total client connections (default none)\n"; } sub print_help () { diff --git a/connectors/vmware/src/centreon/esxd/cmdmemhost.pm b/connectors/vmware/src/centreon/esxd/cmdmemhost.pm index 88f88fadd..95e95db13 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemhost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'memhost'; bless $self, $class; @@ -22,79 +21,134 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($host, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 80); - $self->{crit} = (defined($_[2]) ? $_[2] : 90); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lhost}); - my @properties = ('summary.hardware.memorySize', 'runtime.connectionState'); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'summary.hardware.memorySize', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - - my $memory_size = $$result[0]->{'summary.hardware.memorySize'}; - + if (scalar(@$result) > 1) { + $multiple = 1; + } my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])); - my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - if ($mem_used * 100 / ($memory_size / 1024) >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All memory usages are ok")); } - if ($mem_used * 100 / ($memory_size / 1024) >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + my $memory_size = $entity_view->{'summary.hardware.memorySize'}; # in B + + # in KB + my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_free = $memory_size - $mem_used; + my $prct_used = $mem_used * 100 / $memory_size; + my $prct_free = 100 - $prct_used; + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); + my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_used); + my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $entity_view->{name}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $entity_view->{name}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', + value => $mem_used, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', total => $memory_size, cast_int => 1), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', total => $memory_size, cast_int => 1), + min => 0, max => $memory_size); + $self->{manager}->{output}->perfdata_add(label => 'overhead' . $extra_label, unit => 'B', + value => $mem_overhead, + min => 0); } - - $output = "Memory used : " . centreon::esxd::common::simplify_number($mem_used / 1024 / 1024) . " Go - size : " . centreon::esxd::common::simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . centreon::esxd::common::simplify_number($mem_used * 100 / ($memory_size / 1024)) . " %"; - $output .= "|used=" . ($mem_used * 1024) . "o;" . centreon::esxd::common::simplify_number($memory_size * $self->{warn} / 100, 0) . ";" . centreon::esxd::common::simplify_number($memory_size * $self->{crit} / 100, 0) . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o"; - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm index fbd52611f..f196e1345 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'swaphost'; bless $self, $class; @@ -22,77 +21,130 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($host, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 0.8); - $self->{crit} = (defined($_[2]) ? $_[2] : 1); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lhost}); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } my @properties = ('name', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - + if (scalar(@$result) > 1) { + $multiple = 1; + } my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{obj_esxd}->{perfcounter_speriod}); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])); - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if (($swap_in / 1024) >= $self->{warn} || ($swap_out / 1024) >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All swap rate usages are ok")); } - if (($swap_in / 1024) >= $self->{crit} || ($swap_out / 1024) >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + # KBps + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); + my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Swap In: %s Swap Out: %s", + $entity_view->{name}, + $swap_in_value . " " . $swap_in_unit . "/s", + $swap_out_value . " " . $swap_out_unit . "/s")); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Swap In: %s Swap Out: %s", + $entity_view->{name}, + $swap_in_value . " " . $swap_in_unit . "/s", + $swap_out_value . " " . $swap_out_unit . "/s")); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'swap_in' . $extra_label, unit => 'B/s', + value => $swap_in, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'swap_out' . $extra_label, unit => 'B/s', + value => $swap_out, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); } - - $output = "Swap In : " . centreon::esxd::common::simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . centreon::esxd::common::simplify_number($swap_out / 1024 * 8) . " Mb/s "; - $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmduptimehost.pm b/connectors/vmware/src/centreon/esxd/cmduptimehost.pm index b1457a400..0550aec9e 100644 --- a/connectors/vmware/src/centreon/esxd/cmduptimehost.pm +++ b/connectors/vmware/src/centreon/esxd/cmduptimehost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'uptimehost'; bless $self, $class; @@ -22,55 +21,117 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($lhost) = @_; + my ($self, %options) = @_; - if (!defined($lhost) || $lhost eq "") { - $self->{logger}->writeLogError("ARGS error: need host name"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); return 1; } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; + } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if ($self->{obj_esxd}->{module_date_parse_loaded} == 0) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Need to install Date::Parse Perl Module.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Need to install Date::Parse Perl Module."); return ; } - my %filters = ('name' => $self->{lhost}); - my @properties = ('runtime.bootTime', 'runtime.connectionState'); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'runtime.bootTime', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All uptimes are ok")); } - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); - my $create_time = Date::Parse::str2time($$result[0]->{'runtime.bootTime'}); - if (!defined($create_time)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't Parse date '" . $$result[0]->{'runtime.bootTime'} . "'.\n"); - return ; + my $create_time = Date::Parse::str2time($entity_view->{'runtime.bootTime'}); + if (!defined($create_time)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't Parse date '" . $entity_view->{'runtime.bootTime'} . "'"); + return ; + } + + my $diff_time = time() - $create_time; + my $days = int($diff_time / 60 / 60 / 24); + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Uptime: %s day(s)", + $entity_view->{name}, + $days)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Uptime: %s day(s)", + $entity_view->{name}, + $days)); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'uptime' . $extra_label, unit => 's', + value => $diff_time, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); } - my $diff_time = time() - $create_time; - my $days = int($diff_time / 60 / 60 / 24); - - my $output = ''; - my $status = 0; # OK - - $output = "Uptime (in day): $days|uptime=" . $days . "day(s)\n"; - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; From eaee5ccbd31b11cfc07c5c9955de659b800b0eff Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 27 Oct 2014 14:02:42 +0100 Subject: [PATCH 097/447] Refs #7246 --- connectors/vmware/centreon_esx_client.pl | 15 - .../src/centreon/esxd/cmdcountvmhost.pm | 170 +++++---- .../vmware/src/centreon/esxd/cmdnethost.pm | 334 ++++++++++-------- connectors/vmware/src/centreon/esxd/common.pm | 127 +++++-- 4 files changed, 378 insertions(+), 268 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index a7b0d812f..2114f211c 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -144,14 +144,6 @@ sub print_usage () { print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print " --skip-errors Status OK if not enough permissions or others errors (when you checks multiples)\n"; print "\n"; - print "'nethost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --nic Physical nic name to check (required)\n"; - print " -w (--warning) Warning Threshold in percent (default 80)\n"; - print " -c (--critical) Critical Threshold in percent (default 90)\n"; - print " --filter Use regexp for --nic option (can check multiple nics at once)\n"; - print " --skip-errors Status OK if some nic are down (when you checks multiples)\n"; - print "\n"; print "'datastoreshost':\n"; print " -e (--esx-host) Esx Host to check (required)\n"; print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; @@ -159,13 +151,6 @@ sub print_usage () { print " --datastore Datastores to check (can use a regexp with --filter)\n"; print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print "\n"; - print "'countvmhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold if more VMs on (default none)\n"; - print " -c (--critical) Critical Threshold if more VMs on (default none)\n"; - print " --warning2 Warning Threshold if more VMs not on (default none)\n"; - print " --critical2 Critical Threshold if more VMs not on (default none)\n"; - print "\n"; print "'cpuvm':\n"; print " --vm VM to check (required)\n"; print " -w (--warning) Warning Threshold in percent for cpu average (default 80)\n"; diff --git a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm index e45182c02..7601a0987 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'countvmhost'; bless $self, $class; @@ -22,108 +21,131 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($lhost, $warn, $crit, $warn2, $crit2) = @_; + my ($self, %options) = @_; - if (!defined($lhost) || $lhost eq "") { - $self->{logger}->writeLogError("ARGS error: need host name"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; - } - if (defined($warn2) && $warn2 ne "" && $warn2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn2 threshold must be a positive number"); - return 1; - } - if (defined($crit2) && $crit2 ne "" && $crit2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit2 threshold must be a positive number"); - return 1; - } - if (defined($warn2) && defined($crit2) && $warn2 ne "" && $crit2 ne "" && $warn2 > $crit2) { - $self->{logger}->writeLogError("ARGS error: warn2 threshold must be lower than crit2 threshold"); - return 1; + foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : ''); - $self->{crit} = (defined($_[2]) ? $_[2] : ''); - $self->{warn2} = (defined($_[3]) ? $_[3] : ''); - $self->{crit2} = (defined($_[4]) ? $_[4] : ''); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = ('name' => $self->{lhost}); - my @properties = ('vm', 'runtime.connectionState'); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'vm', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; } - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); + #return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + # $$result[0]->{'runtime.connectionState'}->val) == 0); my @vm_array = (); foreach my $entity_view (@$result) { - if (defined $entity_view->vm) { + if (defined($entity_view->vm)) { @vm_array = (@vm_array, @{$entity_view->vm}); } } @properties = ('runtime.powerState'); - $result = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); - if (!defined($result)) { - return ; + my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + return if (!defined($result2)); + + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All ESX Hosts are ok")); } - my $output = ''; - my $status = 0; # OK - my $num_poweron = 0; - my $num_powerother = 0; - - foreach (@$result) { - my $power_value = lc($_->{'runtime.powerState'}->val); - if ($power_value eq 'poweredon') { - $num_poweron++; - } else { - $num_powerother++; + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + my %vm_states = (poweredon => 0, poweredoff => 0, suspended => 0); + if (defined($entity_view->vm)) { + foreach my $vm_host (@{$entity_view->vm}) { + foreach my $vm (@{$result2}) { + if ($vm_host->{value} eq $vm->{mo_ref}->{value}) { + my $power_value = lc($vm->{'runtime.powerState'}->val); + $vm_states{$power_value}++; + last; + } + } + } + } + + foreach my $labels ((['poweredon', 'warning_on', 'critical_on'], + ['poweredoff', 'warning_off', 'critical_off'], + ['suspended', 'warning_suspended', 'critical_suspended'])) { + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $vm_states{$labels->[0]}, + threshold => [ { label => $labels->[2], exit_litteral => 'critical' }, + { label => $labels->[1], exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{name}, + $vm_states{$labels->[0]}, + $labels->[0])); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{name}, + $vm_states{$labels->[0]}, + $labels->[0])); + } + + $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, + value => $vm_states{$labels->[0]}, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), + min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); } } - if (defined($self->{crit}) && $self->{crit} ne "" && ($num_poweron >= $self->{crit})) { - $output = "CRITICAL: $num_poweron VM running"; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($num_poweron >= $self->{warn})) { - $output = "WARNING: $num_poweron VM running"; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } else { - $output .= "OK: $num_poweron VM running"; - } - - if (defined($self->{crit2}) && $self->{crit2} ne "" && ($num_powerother >= $self->{crit2})) { - $output .= " - CRITICAL: $num_powerother VM not running."; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn2}) && $self->{warn2} ne "" && ($num_powerother >= $self->{warn2})) { - $output .= " - WARNING: $num_powerother VM not running."; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } else { - $output .= " - OK: $num_powerother VM not running."; - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|count_on=$num_poweron;$self->{warn};$self->{crit};0; count_not_on=$num_powerother;$self->{warn2};$self->{crit2};0;\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdnethost.pm b/connectors/vmware/src/centreon/esxd/cmdnethost.pm index 6d1271e4e..8c921edff 100644 --- a/connectors/vmware/src/centreon/esxd/cmdnethost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdnethost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'nethost'; bless $self, $class; @@ -21,192 +20,239 @@ sub getCommandName { return $self->{commandName}; } -sub checkArgs { - my $self = shift; - my ($host, $pnic, $filter, $warn, $crit) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); return 1; } - if (!defined($pnic) || $pnic eq "") { - $self->{logger}->writeLogError("ARGS error: need physical nic name"); + if (defined($options{arguments}->{nic_name}) && $options{arguments}->{nic_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: nic name cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + if (defined($options{arguments}->{link_down_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{link_down_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for link down status '" . $options{arguments}->{link_down_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{pnic} = $_[1]; - $self->{filter} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; - $self->{warn} = (defined($_[3]) ? $_[3] : 80); - $self->{crit} = (defined($_[4]) ? $_[4] : 90); - $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lhost}); - my @properties = ('config.network.pnic', 'runtime.connectionState', 'config.network.vswitch', 'config.network.proxySwitch'); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'config.network.pnic', 'runtime.connectionState', 'config.network.vswitch', 'config.network.proxySwitch'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All traffics are ok")); } - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - - my %nic_in_vswitch = (); - my %pnic_def_up = (); - my %pnic_def_down = (); - my $instances = []; - my $filter_ok = 0; - - # Get Name from vswitch - if (defined($$result[0]->{'config.network.vswitch'})) { - foreach (@{$$result[0]->{'config.network.vswitch'}}) { - next if (!defined($_->{pnic})); - foreach my $keynic (@{$_->{pnic}}) { - $nic_in_vswitch{$keynic} = 1; + my $pnic_def_up = {}; + my $pnic_def_down = {}; + my $query_perfs = []; + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + $pnic_def_up->{$entity_view->{mo_ref}->{value}} = {}; + $pnic_def_down->{$entity_view->{mo_ref}->{value}} = {}; + my %nic_in_vswitch = (); + my $instances = []; + my $filter_ok = 0; + + # Get Name from vswitch + if (defined($entity_view->{'config.network.vswitch'})) { + foreach (@{$entity_view->{'config.network.vswitch'}}) { + next if (!defined($_->{pnic})); + foreach my $keynic (@{$_->{pnic}}) { + $nic_in_vswitch{$keynic} = 1; + } } } - } - # Get Name from proxySwitch - if (defined($$result[0]->{'config.network.proxySwitch'})) { - foreach (@{$$result[0]->{'config.network.proxySwitch'}}) { - next if (!defined($_->{pnic})); - foreach my $keynic (@{$_->{pnic}}) { - $nic_in_vswitch{$keynic} = 1; + # Get Name from proxySwitch + if (defined($entity_view->{'config.network.proxySwitch'})) { + foreach (@{$entity_view->{'config.network.proxySwitch'}}) { + next if (!defined($_->{pnic})); + foreach my $keynic (@{$_->{pnic}}) { + $nic_in_vswitch{$keynic} = 1; + } } } - } - foreach (@{$$result[0]->{'config.network.pnic'}}) { - # Not in vswitch. Skip - if (!defined($nic_in_vswitch{$_->key})) { + foreach (@{$entity_view->{'config.network.pnic'}}) { + # Not in vswitch. Skip + next if (!defined($nic_in_vswitch{$_->key})); + + # Check filter + if (defined($self->{nic_name}) && !defined($self->{filter_nic}) && $_->device ne $self->{nic_name}) { + next; + } elsif (defined($self->{nic_name}) && defined($self->{filter_nic}) && $_->device !~ /$self->{nic_name}/) { + next; + } + $filter_ok = 1; + if (defined($_->linkSpeed)) { + $pnic_def_up->{$entity_view->{mo_ref}->{value}}->{$_->device} = $_->linkSpeed->speedMb; + push @$instances, $_->device; + } else { + $pnic_def_down->{$entity_view->{mo_ref}->{value}}->{$_->device} = 1; + } + } + + if ($filter_ok == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("%s can't get physical nic with filter '%s'. (or physical nic not in a 'vswitch' or 'dvswitch'", + $entity_view->{name}, $self->{nic_name})); + next; + } + if (scalar(@${instances}) == 0 && + ($multiple == 0 || ($multiple == 1 && !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1)))) { + $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, + short_msg => sprintf("%s Link(s) '%s' is(are) down", + $entity_view->{name}, join("','", keys %{$pnic_def_down->{$entity_view->{mo_ref}->{value}}}))); next; } - - # Check filter - next if ($self->{filter} == 0 && $_->device !~ /^\Q$self->{pnic}\E$/); - next if ($self->{filter} == 1 && $_->device !~ /$self->{pnic}/); - $filter_ok = 1; - if (defined($_->linkSpeed)) { - $pnic_def_up{$_->device} = $_->linkSpeed->speedMb; - push @$instances, $_->device; - } else { - $pnic_def_down{$_->device} = 1; - } - } + push @$query_perfs, { + entity => $entity_view, + metrics => [ + {label => 'net.received.average', instances => $instances}, + {label => 'net.transmitted.average', instances => $instances} + ] + }; + } - if ($filter_ok == 0) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't get physical nic with filter '$self->{pnic}'. (or physical nic not in a 'vswitch' or 'dvswitch')\n"); - return ; - } - if ($#${instances} == -1) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Link(s) '" . join("','", keys %pnic_def_down) . "' is(are) down.\n"); - return ; - } - - + # Nothing to retrieve. problem before already. + return if (scalar(@$query_perfs) == 0); + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $result, - [{'label' => 'net.received.average', 'instances' => $instances}, - {'label' => 'net.transmitted.average', 'instances' => $instances}], - $self->{obj_esxd}->{perfcounter_speriod}); + undef, + $query_perfs, + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $status = 0; # OK - my $output = ""; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $output_ok_unit = ''; - my $perfdata = ''; - my @nic_downs = keys %pnic_def_down; - if ($#nic_downs >= 0) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "Link(s) '" . join("','", @nic_downs) . "' is(are) down"); - } - } - - foreach (keys %pnic_def_up) { - - my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{'key'} . ":" . $_}[0])); - my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{'key'} . ":" . $_}[0])); - - $output_ok_unit = "Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 100 / $pnic_def_up{$_}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 100 / $pnic_def_up{$_}) . " %)"; - - if (($traffic_in / 1024 * 100 / $pnic_def_up{$_}) >= $self->{crit} || ($traffic_out / 1024 * 100 / $pnic_def_up{$_}) >= $self->{crit}) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ". ", - "'$_' Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 100 / $pnic_def_up{$_}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 100 / $pnic_def_up{$_}) . " %)"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (($traffic_in / 1024 * 100 / $pnic_def_up{$_}) >= $self->{warn} || ($traffic_out / 1024 * 100 / $pnic_def_up{$_}) >= $self->{warn}) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ". ", - "'$_' Traffic In : " . centreon::esxd::common::simplify_number($traffic_in / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_in / 1024 * 100 / $pnic_def_up{$_}) . " %), Out : " . centreon::esxd::common::simplify_number($traffic_out / 1024) . " MB/s (" . centreon::esxd::common::simplify_number($traffic_out / 1024 * 100 / $pnic_def_up{$_}) . " %)"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + if (scalar(keys %{$pnic_def_down->{$entity_value}}) > 0 && + ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1))) { + $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, + short_msg => sprintf("%s Link(s) '%s' is(are) down", + $entity_view->{name}, join("','", keys %{$pnic_def_down->{$entity_value}}))); } - my $warn_perfdata = ($pnic_def_up{$_} * $self->{warn} / 100) * 1024 * 1024; - my $crit_perfdata = ($pnic_def_up{$_} * $self->{crit} / 100) * 1024 * 1024; - - if ($self->{filter} == 1) { - $perfdata .= " 'traffic_in_" . $_ . "'=" . ($traffic_in * 1024) . "B/s;$warn_perfdata;$crit_perfdata;0; 'traffic_out_" . $_ . "'=" . (($traffic_out * 1024)) . "B/s;$warn_perfdata;$crit_perfdata;0;"; - } else { - $perfdata .= " traffic_in=" . ($traffic_in * 1024) . "B/s;$warn_perfdata;$crit_perfdata;0; traffic_out=" . (($traffic_out * 1024)) . "B/s;$warn_perfdata;$crit_perfdata;0;"; - } - } + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (sort keys %{$pnic_def_up->{$entity_value}}) { + # KBps + my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $interface_speed = $pnic_def_up->{$entity_value}->{$_} * 1024 * 1024; + my $in_prct = $traffic_in * 100 / $interface_speed; + my $out_prct = $traffic_out * 100 / $interface_speed; + + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical_in', exit_litteral => 'critical' }, { label => 'warning_in', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical_out', exit_litteral => 'critical' }, { label => 'warning_out', exit_litteral => 'warning' } ]); - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $output_warning"; - } - if ($status == 0) { - if ($self->{filter} == 1) { - $output .= $output_append . "All traffics are ok"; - } else { - $output .= $output_append . $output_ok_unit; + my ($in_value, $in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $traffic_in, network => 1); + my ($out_value, $out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $traffic_out, network => 1); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + push @exits, $exit; + + my $output = sprintf("Interface '%s' Traffic In : %s/s (%.2f %%), Out : %s/s (%.2f %%) ", $_, + $in_value . $in_unit, $in_prct, + $out_value . $out_unit, $out_prct); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'traffic_in' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $traffic_in), + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-in', total => $interface_speed), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-in', total => $interface_speed), + min => 0, max => $interface_speed); + $self->{manager}->{output}->perfdata_add(label => 'traffic_out' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $traffic_out), + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-out', total => $interface_speed), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-out', total => $interface_speed), + min => 0, max => $interface_speed); + } + + $self->{manager}->{output}->output_add(long_msg => "$entity_view->{name}' $long_msg"); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => "'$entity_view->{name}' $short_msg" + ); + } + if ($multiple == 0) { + $self->{manager}->{output}->output_add(short_msg => "'$entity_view->{name}' $long_msg"); } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index afd589270..1b268e7e2 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -163,14 +163,14 @@ sub get_perf_metric_ids { 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'}, + if (defined($obj_esxd->{perfcounter_cache}->{$_->{label}})) { + foreach my $instance (@{$_->{instances}}) { + my $metric = PerfMetricId->new(counterId => $obj_esxd->{perfcounter_cache}->{$_->{label}}{key}, instance => $instance); push @$filtered_list, $metric; } } else { - $obj_esxd->{logger}->writeLogError("Metric '" . $_->{'label'} . "' unavailable."); + $obj_esxd->{logger}->writeLogError("Metric '" . $_->{label} . "' unavailable."); $manager_display->{output}->output_add(severity => 'UNKNOWN', short_msg => "Counter doesn't exist. VMware version can be too old."); return undef; @@ -179,45 +179,102 @@ sub get_perf_metric_ids { return $filtered_list; } +sub performance_builder_specific { + my (%options) = @_; + + my @perf_query_spec; + foreach my $entry (@{$options{metrics}}) { + my $perf_metric_ids = get_perf_metric_ids($options{connector}, $entry->{metrics}); + return undef if (!defined($perf_metric_ids)); + + my $tstamp = time(); + my (@t) = gmtime($tstamp - $options{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 ($options{interval} == 20) { + push @perf_query_spec, PerfQuerySpec->new(entity => $entry->{entity}, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => 20, + startTime => $startTime, + endTime => $endTime, + maxSample => 1); + } else { + push @perf_query_spec, PerfQuerySpec->new(entity => $entry->{entity}, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => $options{interval}, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); + } + } + + return $options{connector}->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); +} + +sub performance_builder_global { + my (%options) = @_; + + my @perf_query_spec; + my $perf_metric_ids = get_perf_metric_ids($options{connector}, $options{metrics}); + return undef if (!defined($perf_metric_ids)); + + my $tstamp = time(); + my (@t) = gmtime($tstamp - $options{interval}); + my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + (@t) = gmtime($tstamp); + my $endTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + + foreach (@{$options{views}}) { + if ($options{interval} == 20) { + push @perf_query_spec, PerfQuerySpec->new(entity => $_, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => 20, + startTime => $startTime, + endTime => $endTime, + maxSample => 1); + } else { + push @perf_query_spec, PerfQuerySpec->new(entity => $_, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => $options{interval}, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); + } + } + + return $options{connector}->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); +} + sub generic_performance_values_historic { my ($obj_esxd, $views, $perfs, $interval, %options) = @_; my $counter = 0; my %results; eval { - my $perf_metric_ids = get_perf_metric_ids($obj_esxd, $perfs); - return undef if (!defined($perf_metric_ids)); - - my @perf_query_spec; - my $tstamp = time(); - my (@t) = gmtime($tstamp - $interval); - my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); - (@t) = gmtime($tstamp); - my $endTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + my $perfdata; - foreach (@$views) { - if ($interval == 20) { - push @perf_query_spec, PerfQuerySpec->new(entity => $_, - metricId => $perf_metric_ids, - format => 'normal', - intervalId => 20, - startTime => $startTime, - endTime => $endTime, - maxSample => 1); - } else { - push @perf_query_spec, PerfQuerySpec->new(entity => $_, - metricId => $perf_metric_ids, - format => 'normal', - intervalId => $interval, - startTime => $startTime, - endTime => $endTime - ); - #maxSample => 1); - } + if (defined($views)) { + $perfdata = performance_builder_global(connector => $obj_esxd, + views => $views, + metrics => $perfs, + interval => $interval); + } else { + $perfdata = performance_builder_specific(connector => $obj_esxd, + metrics => $perfs, + interval => $interval); } - my $perfdata = $obj_esxd->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); + return undef if (!defined($perfdata)); if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { $manager_display->{output}->output_add(severity => 'UNKNOWN', From a03d67da0064ddb605ff7ed7f2cb398cfb511b50 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 27 Oct 2014 17:11:59 +0100 Subject: [PATCH 098/447] Refs #7246 WIP in migration --- connectors/vmware/centreon_esx_client.pl | 40 ---- .../vmware/src/centreon/esxd/cmdcpuhost.pm | 1 - .../vmware/src/centreon/esxd/cmdcpuvm.pm | 183 ++++++++++------ .../vmware/src/centreon/esxd/cmdlimitvm.pm | 192 +++++++++-------- .../vmware/src/centreon/esxd/cmdmemvm.pm | 160 ++++++++++---- .../vmware/src/centreon/esxd/cmdnethost.pm | 2 +- .../vmware/src/centreon/esxd/cmdsnapshotvm.pm | 197 +++++++++--------- .../vmware/src/centreon/esxd/cmdswaphost.pm | 7 +- .../vmware/src/centreon/esxd/cmdswapvm.pm | 141 +++++++++---- .../vmware/src/centreon/esxd/cmdtoolsvm.pm | 178 +++++++++------- connectors/vmware/src/centreon/esxd/common.pm | 30 ++- 11 files changed, 653 insertions(+), 478 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 2114f211c..de3dae11a 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -151,51 +151,11 @@ sub print_usage () { print " --datastore Datastores to check (can use a regexp with --filter)\n"; print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print "\n"; - print "'cpuvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent for cpu average (default 80)\n"; - print " -c (--critical) Critical Threshold in percent for cpu average (default 90)\n"; - print " --warning2 Warning Threshold in percent for cpu ready (default 5)\n"; - print " --critical2 Critical Threshold in percent for cpu ready (default 10)\n"; - print "\n"; - print "'toolsvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; - print " --skip-not-running Skip vmtools for vms not running (also template)\n"; - print "\n"; - print "'snapshotvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --warning Warning threshold in seconds (default: 3 days)\n"; - print " --critical Critical threshold in seconds (default: 5 days)\n"; - print " --check-consolidation Check if VM needs consolidation (since vsphere 5.0)\n"; - print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; - print " --skip-not-running Skip snapshots for vms not running\n"; - print "\n"; - print "'limitvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --warn Warning threshold if set (default)\n"; - print " --crit Critical threshold if set\n"; - print " --check-disk Check Disk limits (since vsphere 5.0)\n"; - print " --skip-errors Status OK if vms are disconencted (when you checks multiples)\n"; - print "\n"; print "'datastoresvm':\n"; print " --vm VM to check (required)\n"; print " -w (--warning) Warning Threshold in IOPS (default none)\n"; print " -c (--critical) Critical Threshold in IOPS (default none)\n"; print "\n"; - print "'memvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in percent\n"; - print " -c (--critical) Critical Threshold in percent\n"; - print "\n"; - print "'swapvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in MB/s (default 0.8)\n"; - print " -c (--critical) Critical Threshold in MB/s (default 1)\n"; - print "\n"; print "'thinprovisioningvm':\n"; print " --vm VM to check (required)\n"; print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm index a4907fa6e..e4ea4202e 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm @@ -20,7 +20,6 @@ sub getCommandName { return $self->{commandName}; } - sub checkArgs { my ($self, %options) = @_; diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm index b65d83f48..7ca430306 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'cpuvm'; bless $self, $class; @@ -22,113 +21,161 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm, $warn, $crit, $warn2, $crit2) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm hostname"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); + if (defined($options{arguments}->{nopoweredon_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); return 1; } - if (defined($warn2) && $warn2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn2 threshold must be a positive number"); - return 1; - } - if (defined($crit2) && $crit2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit2 threshold must be a positive number"); - return 1; - } - if (defined($warn2) && defined($crit2) && $warn2 > $crit2) { - $self->{logger}->writeLogError("ARGS error: warn2 threshold must be lower than crit2 threshold"); - return 1; + foreach my $label (('warning_usagemhz', 'critical_usagemhz', 'warning_usage', 'critical_usage', 'warning_ready', 'critical_ready')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 80); - $self->{crit} = (defined($_[2]) ? $_[2] : 90); - $self->{warn2} = (defined($_[3]) ? $_[3] : 5); - $self->{crit2} = (defined($_[4]) ? $_[4] : 10); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_usagemhz', 'critical_usagemhz', 'warning_usage', 'critical_usage', 'warning_ready', 'critical_ready')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lvm}); + my %filters = (); + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{vm_hostname}/; + } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, - $$result[0]->{'runtime.connectionState'}->val, - $$result[0]->{'runtime.powerState'}->val) == 0); + return if (!defined($result)); my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, {'label' => 'cpu.ready.summation', 'instances' => \@instances}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - my $status = 0; # OK - my $output = ''; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); - my $total_cpu_ready = centreon::esxd::common::simplify_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{obj_esxd}->{perfcounter_speriod} * 1000) * 100); - - if ($total_cpu_average >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if (scalar(@$result) > 1) { + $multiple = 1; } - if ($total_cpu_average >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All cpu usages are ok")); } - if ($total_cpu_ready >= $self->{warn2}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if ($total_cpu_ready >= $self->{crit2}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } - + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + power => $entity_view->{'runtime.powerState'}->val, + status => $self->{disconnect_status}, + powerstatus => $self->{nopoweredon_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_ready = centreon::esxd::common::simplify_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{obj_esxd}->{perfcounter_speriod} * 1000) * 100); + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + foreach my $entry (({ value => $total_cpu_average, label => 'usage', output => 'Total Average CPU usage %s %%', + perf_label => 'cpu_total', perf_min => 0, perf_max => 100, perf_unit => '%' }, + { value => $total_cpu_mhz_average, label => 'usagemhz', output => 'Total Average CPU %s Mhz', + perf_label => 'cpu_total_MHz', perf_min => 0, perf_unit => 'MHz'}, + { value => $total_cpu_ready, label => 'ready', output => 'CPU ready %s %%', + perf_label => 'cpu_ready', perf_min => 0, perf_unit => '%' })) { + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $entry->{value}, threshold => [ { label => 'critical_' . $entry->{label}, exit_litteral => 'critical' }, { label => 'warning_' . $entry->{label}, exit_litteral => 'warning' } ]); + push @exits, $exit; + + my $output = sprintf($entry->{output}, $entry->{value}); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $self->{manager}->{output}->perfdata_add(label => $entry->{perf_label} . $extra_label, unit => $entry->{perf_unit}, + value => $entry->{value}, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_' . $entry->{label}), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_in' . $entry->{label}), + min => $entry->{perf_min}, max => $entry->{perf_max}); + } + + $long_msg .= ' on last ' . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . ' min'; - $output = "CPU ready '$total_cpu_ready%', Total Average CPU usage '$total_cpu_average%', Total Average CPU '" . $total_cpu_mhz_average . "MHz' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_ready=$total_cpu_ready%;$self->{warn2};$self->{crit2};0; cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100 cpu_total_MHz=" . $total_cpu_mhz_average . "MHz"; - - foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' $long_msg"); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => "'$entity_view->{name}' $short_msg" + ); + } + if ($multiple == 0) { + $self->{manager}->{output}->output_add(short_msg => "'$entity_view->{name}' $long_msg"); + } + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; $cia = -1 if (!defined($cia) || $cia eq ""); $cib = -1 if (!defined($cib) || $cib eq ""); - $cia <=> $cib} keys %$values) { - my ($counter_id, $instance) = split /:/, $id; - next if ($self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} != $counter_id); - if ($instance ne "") { - $output .= " cpu" . $instance . "_MHz=" . centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$id}[0])) . "MHz"; + $cia <=> $cib} keys %{$values->{$entity_value}}) { + my ($counter_id, $instance) = split /:/, $id; + next if ($self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} != $counter_id); + if ($instance ne "") { + $self->{manager}->{output}->perfdata_add(label => 'cpu_' . $instance . '_MHz' . $extra_label, unit => 'MHz', + value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0])), + min => 0); + } } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm index 16d5c19ff..86e8bc93b 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'limitvm'; bless $self, $class; @@ -22,26 +21,62 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm hostname"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + if (defined($options{arguments}->{cpu_limitset_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{cpu_limitset_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for cpu limitset status '" . $options{arguments}->{cpu_limitset_status} . "'"); + return 1; + } + if (defined($options{arguments}->{memory_limitset_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{memory_limitset_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for memory limitset status '" . $options{arguments}->{memory_limitset_status} . "'"); + return 1; + } + if (defined($options{arguments}->{disk_limitset_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disk_limitset_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disk limitset status '" . $options{arguments}->{disk_limitset_status} . "'"); return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; - $self->{crit} = (defined($_[3]) && $_[3] == 1) ? 1 : 0; - $self->{disk} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; - $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; - if ($self->{warn} == 0 && $self->{crit} == 0) { - $self->{warn} = 1; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub display_verbose { + my ($self, %options) = @_; + + $self->{manager}->{output}->output_add(long_msg => $options{label}); + foreach my $vm (sort keys %{$options{vms}}) { + $self->{manager}->{output}->output_add(long_msg => ' ' . $vm); } } @@ -49,106 +84,89 @@ sub run { my $self = shift; my %filters = (); - - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{lvm}\E$/; + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{lvm}/; + $filters{name} = qr/$self->{vm_hostname}/; } my @properties; - push @properties, 'name', 'runtime.connectionState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'; - if ($self->{disk} == 1) { + push @properties, 'name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'; + if (defined($self->{check_disk_limit})) { push @properties, 'config.hardware.device'; } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Limits are ok")); + } else { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("Limits are ok")); } - - my $status = 0; # OK - my $output = ""; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - foreach my $virtual (@$result) { - if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $virtual->{name} . "' not connected"); - } - next; - } + my %cpu_limit = (); + my %memory_limit = (); + my %disk_limit = (); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + nocheck_ps => 1, + multiple => $multiple) == 0); - my $limit_set_warn = ''; - my $limit_set_crit = ''; + next if (defined($self->{nopoweredon_skip}) && + !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); # CPU Limit - if ($self->{crit} == 1 && defined($virtual->{'config.cpuAllocation.limit'}) && $virtual->{'config.cpuAllocation.limit'} != -1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $limit_set_crit = "/CPU" - } elsif ($self->{warn} == 1 && defined($virtual->{'config.cpuAllocation.limit'}) && $virtual->{'config.cpuAllocation.limit'} != -1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $limit_set_warn = "/CPU" + if (defined($entity_view->{'config.cpuAllocation.limit'}) && $entity_view->{'config.cpuAllocation.limit'} != -1) { + $cpu_limit{$entity_view->{name}} = 1; } # Memory Limit - if ($self->{crit} == 1 && defined($virtual->{'config.memoryAllocation.limit'}) && $virtual->{'config.memoryAllocation.limit'} != -1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $limit_set_crit .= "/MEM" - } elsif ($self->{warn} == 1 && defined($virtual->{'config.memoryAllocation.limit'}) && $virtual->{'config.memoryAllocation.limit'} != -1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $limit_set_warn .= "/MEM" + if (defined($entity_view->{'config.memoryAllocation.limit'}) && $entity_view->{'config.memoryAllocation.limit'} != -1) { + $memory_limit{$entity_view->{name}} = 1; } # Disk - if ($self->{disk} == 1) { - foreach my $device (@{$virtual->{'config.hardware.device'}}) { + if (defined($self->{check_disk_limit})) { + foreach my $device (@{$entity_view->{'config.hardware.device'}}) { if ($device->isa('VirtualDisk')) { - if ($self->{crit} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $limit_set_crit .= "/DISK" - } elsif ($self->{warn} == 1 && defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $limit_set_warn .= "/DISK" + if (defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { + $disk_limit{$entity_view->{name}} = 1; + last; } } } - } - - # Set - if ($limit_set_crit ne '') { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "[" . $virtual->{name}. "]$limit_set_crit"); - } elsif ($limit_set_warn ne '') { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "[" . $virtual->{name}. "]$limit_set_warn"); - } - + } } - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; + if (scalar(keys %cpu_limit) > 0 && + !$self->{manager}->{output}->is_status(value => $self->{cpu_limitset_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{cpu_limitset_status}, + short_msg => sprintf('%d VM with CPU limits', scalar(keys %cpu_limit))); + $self->display_verbose(label => 'CPU limits:', vms => \%cpu_limit); } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Limits for VMs: $output_critical"; - $output_append = ". "; + if (scalar(keys %memory_limit) > 0 && + !$self->{manager}->{output}->is_status(value => $self->{memory_limitset_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{memory_limitset_status}, + short_msg => sprintf('%d VM with memory limits', scalar(keys %memory_limit))); + $self->display_verbose(label => 'Memory limits:', vms => \%memory_limit); } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Limits for VMs: $output_warning"; + if (scalar(keys %disk_limit) > 0 && + !$self->{manager}->{output}->is_status(value => $self->{disk_limitset_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{disk_limitset_status}, + short_msg => sprintf('%d VM with disk limits', scalar(keys %disk_limit))); + $self->display_verbose(label => 'Disk limits:', vms => \%disk_limit); } - if ($status == 0) { - $output .= $output_append . "Limits are ok"; - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm index 9bface947..a377ff775 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'memvm'; bless $self, $class; @@ -22,57 +21,78 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm name"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($warn) && $warn ne '' && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit ne '' && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + if (defined($options{arguments}->{nopoweredon_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && $warn ne '' && $crit ne '' && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : undef); - $self->{crit} = (defined($_[2]) ? $_[2] : undef); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lvm}); - my @properties = ('summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); + my %filters = (); + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{vm_hostname}/; + } + my @properties = ('name', 'summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); - return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, - $$result[0]->{'runtime.connectionState'}->val, - $$result[0]->{'runtime.powerState'}->val) == 0); - - my $memory_size = $$result[0]->{'summary.config.memorySizeMB'} * 1024 * 1024; - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'mem.active.average', 'instances' => ['']}, @@ -80,28 +100,78 @@ sub run { {'label' => 'mem.vmmemctl.average', 'instances' => ['']}, {'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.shared.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])); - my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])); - my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])); - my $mem_ballooning = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])); - my $mem_shared = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - if (defined($self->{warn}) && $mem_consumed * 100 / ($memory_size / 1024) >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if (scalar(@$result) > 1) { + $multiple = 1; } - if (defined($self->{crit}) && $mem_consumed * 100 / ($memory_size / 1024) >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All memory usages are ok")); } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + power => $entity_view->{'runtime.powerState'}->val, + status => $self->{disconnect_status}, + powerstatus => $self->{nopoweredon_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + my $memory_size = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; + # in KB + my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_ballooning = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_shared = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])) * 1024; + + my $mem_free = $memory_size - $mem_consumed; + my $prct_used = $mem_consumed * 100 / $memory_size; + my $prct_free = 100 - $prct_used; + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); + my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_consumed); + my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); - $output = "Memory usage : " . centreon::esxd::common::simplify_number($mem_consumed / 1024 / 1024) . " Go - size : " . centreon::esxd::common::simplify_number($memory_size / 1024 / 1024 / 1024) . " Go - percent : " . centreon::esxd::common::simplify_number($mem_consumed * 100 / ($memory_size / 1024)) . " %"; - $output .= "|usage=" . ($mem_consumed * 1024) . "o;" . (defined($self->{warn}) ? centreon::esxd::common::simplify_number($memory_size * $self->{warn} / 100, 0) : '') . ";" . (defined($self->{crit}) ? centreon::esxd::common::simplify_number($memory_size * $self->{crit} / 100, 0) : '') . ";0;" . ($memory_size) . " size=" . $memory_size . "o" . " overhead=" . ($mem_overhead * 1024) . "o" . " ballooning=" . ($mem_ballooning * 1024) . "o" . " shared=" . ($mem_shared * 1024) . "o" . " active=" . ($mem_active * 1024) . "o" ; + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $entity_view->{name}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $entity_view->{name}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', + value => $mem_consumed, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', total => $memory_size, cast_int => 1), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', total => $memory_size, cast_int => 1), + min => 0, max => $memory_size); + $self->{manager}->{output}->perfdata_add(label => 'overhead' . $extra_label, unit => 'B', + value => $mem_overhead, + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'ballooning' . $extra_label, unit => 'B', + value => $mem_ballooning, + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'active' . $extra_label, unit => 'B', + value => $mem_active, + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'shared' . $extra_label, unit => 'B', + value => $mem_shared, + min => 0); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdnethost.pm b/connectors/vmware/src/centreon/esxd/cmdnethost.pm index 8c921edff..53d52e9ae 100644 --- a/connectors/vmware/src/centreon/esxd/cmdnethost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdnethost.pm @@ -242,7 +242,7 @@ sub run { min => 0, max => $interface_speed); } - $self->{manager}->{output}->output_add(long_msg => "$entity_view->{name}' $long_msg"); + $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' $long_msg"); my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { $self->{manager}->{output}->output_add(severity => $exit, diff --git a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm index 12dec6b35..bb02c2fbf 100644 --- a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'snapshotvm'; bless $self, $class; @@ -22,155 +21,145 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm, $filter, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm hostname"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{warning} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 86400 * 3); - $self->{critical} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 86400 * 5); - $self->{consolidate} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; - $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; - $self->{skip_not_running} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if ($self->{obj_esxd}->{module_date_parse_loaded} == 0) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Need to install Date::Parse CPAN Module.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Need to install Date::Parse CPAN Module"); return ; } my %filters = (); - - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{lvm}\E$/; + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{lvm}/; + $filters{name} = qr/$self->{vm_hostname}/; } my @properties; push @properties, 'snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'; - if ($self->{consolidate} == 1) { + if (defined($self->{check_consolidation}) == 1) { push @properties, 'runtime.consolidationNeeded'; } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + my %vm_consolidate = (); + my %vm_errors = (warning => {}, critical => {}); + if (scalar(@$result) > 1) { + $multiple = 1; } - - my $status = 0; # OK - my $output = ""; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $output_ok_unit = 'Snapshot(s) OK'; - my $consolidate_vms = ''; - my $consolidate_vms_append = ''; - my ($num_warning, $num_critical) = (0, 0); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All snapshots are ok")); + } else { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("Snapshot(s) OK")); + } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + nocheck_ps => 1, + multiple => $multiple) == 0); - foreach my $virtual (@$result) { - if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $virtual->{name} . "' not connected"); - } - next; - } - - if ($self->{skip_not_running} == 1 && - !centreon::esxd::common::is_running($virtual->{'runtime.powerState'}->val)) { - next; - } + next if (defined($self->{nopoweredon_skip}) && + !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); - if ($self->{consolidate} == 1 && defined($virtual->{'runtime.consolidationNeeded'}) && $virtual->{'runtime.consolidationNeeded'} =~ /^true|1$/i) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $consolidate_vms .= $consolidate_vms_append . '[' . $virtual->{'name'} . ']'; - $consolidate_vms_append = ', '; + if (defined($self->{check_consolidation}) && defined($entity_view->{'runtime.consolidationNeeded'}) && $entity_view->{'runtime.consolidationNeeded'} =~ /^true|1$/i) { + $vm_consolidate{$entity_view->{name}} = 1; } - if (!defined($virtual->{'snapshot.rootSnapshotList'})) { - next; - } + next if (!defined($entity_view->{'snapshot.rootSnapshotList'})); - foreach my $snapshot (@{$virtual->{'snapshot.rootSnapshotList'}}) { + foreach my $snapshot (@{$entity_view->{'snapshot.rootSnapshotList'}}) { # 2012-09-21T14:16:17.540469Z my $create_time = Date::Parse::str2time($snapshot->createTime); if (!defined($create_time)) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "Can't Parse date '" . $snapshot->createTime . "' for vm [" . $virtual->{'name'} . "]"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't Parse date '" . $snapshot->createTime . "' for vm '" . $entity_view->{name} . "'"); next; } - if (time() - $create_time >= $self->{critical}) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "[" . $virtual->{'name'}. "]"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $num_critical++; - last; - } elsif (time() - $create_time >= $self->{warning}) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "[" . $virtual->{'name'}. "]"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $num_warning++; - last; + + my $diff_time = time() - $create_time; + my $days = int($diff_time / 60 / 60 / 24); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $vm_errors{$exit}->{$entity_view->{name}} = 1; + $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' snapshot create time: " . $snapshot->createTime); } } } - my $perfdata = 'num_warning=' . $num_warning . ' num_critical=' . $num_critical; - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; + $self->{manager}->{output}->perfdata_add(label => 'num_warning', + value => scalar(keys %{$vm_errors{warning}}), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'num_critical', + value => scalar(keys %{$vm_errors{critical}}), + min => 0); + if (scalar(keys %{$vm_errors{warning}}) > 0) { + $self->{manager}->{output}->output_add(severity => 'WARNING', + short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{warning} / 86400), + join('] [', sort keys %{$vm_errors{warning}}))); } - if ($consolidate_vms ne "") { - $output .= $output_append . "CRITICAL - VMs need consolidation : " . $consolidate_vms; - $output_append = ". "; + if (scalar(keys %{$vm_errors{critical}}) > 0) { + $self->{manager}->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{critical} / 86400), + join('] [', sort keys %{$vm_errors{critical}}))); } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Snapshots for VM older than " . ($self->{critical} / 86400) . " days: $output_critical"; - $output_append = ". "; + if (scalar(keys %vm_consolidate) > 0) { + $self->{manager}->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf('VMs need consolidation: [%s]', + join('] [', sort keys %vm_consolidate))); } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Snapshots for VM older than " . ($self->{warning} / 86400) . " days: $output_warning"; - } - if ($status == 0) { - if ($self->{filter} == 1) { - $output .= $output_append . "All snapshots are ok"; - } else { - $output .= $output_append . $output_ok_unit; - } - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm index f196e1345..7de9ec34e 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm @@ -94,7 +94,8 @@ sub run { $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); if ($multiple == 1) { @@ -110,8 +111,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm index 03a8df3f1..639a57c27 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'swapvm'; bless $self, $class; @@ -22,78 +21,140 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm name"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); + if (defined($options{arguments}->{nopoweredon_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 0.8); - $self->{crit} = (defined($_[2]) ? $_[2] : 1); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lvm}); + my %filters = (); + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{vm_hostname}/; + } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } + return if (!defined($result)); - return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, - $$result[0]->{'runtime.connectionState'}->val, - $$result[0]->{'runtime.powerState'}->val) == 0); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])); - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])); - my $status = 0; # OK - my $output = ''; - - if (($swap_in / 1024) >= $self->{warn} || ($swap_out / 1024) >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + + if (scalar(@$result) > 1) { + $multiple = 1; } - if (($swap_in / 1024) >= $self->{crit} || ($swap_out / 1024) >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All swap rate usages are ok")); } + + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + power => $entity_view->{'runtime.powerState'}->val, + status => $self->{disconnect_status}, + powerstatus => $self->{nopoweredon_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; - $output = "Swap In : " . centreon::esxd::common::simplify_number($swap_in / 1024 * 8) . " Mb/s , Swap Out : " . centreon::esxd::common::simplify_number($swap_out / 1024 * 8) . " Mb/s "; - $output .= "|swap_in=" . ($swap_in * 1024 * 8) . "b/s swap_out=" . (($swap_out * 1024 * 8)) . "b/s"; + # KBps + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); + my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Swap In: %s Swap Out: %s", + $entity_view->{name}, + $swap_in_value . " " . $swap_in_unit . "/s", + $swap_out_value . " " . $swap_out_unit . "/s")); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Swap In: %s Swap Out: %s", + $entity_view->{name}, + $swap_in_value . " " . $swap_in_unit . "/s", + $swap_out_value . " " . $swap_out_unit . "/s")); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'swap_in' . $extra_label, unit => 'B/s', + value => $swap_in, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'swap_out' . $extra_label, unit => 'B/s', + value => $swap_out, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm index 4daabaa5a..8e91fe13c 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'toolsvm'; bless $self, $class; @@ -22,110 +21,133 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm hostname"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{tools_notinstalled_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{tools_notinstalled_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for tools notinstalled status '" . $options{arguments}->{tools_notinstalled_status} . "'"); + return 1; + } + if (defined($options{arguments}->{tools_notrunning_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{tools_notrunning_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for tools notrunning status '" . $options{arguments}->{tools_notrunning_status} . "'"); + return 1; + } + if (defined($options{arguments}->{tools_notupd2date_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{tools_notupd2date_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for tools notupd2date status '" . $options{arguments}->{tools_notupd2date_status} . "'"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{skip_errors} = (defined($_[2]) && $_[2] == 1) ? 1 : 0; - $self->{skip_not_running} = (defined($_[3]) && $_[3] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub display_verbose { + my ($self, %options) = @_; + + $self->{manager}->{output}->output_add(long_msg => $options{label}); + foreach my $vm (sort keys %{$options{vms}}) { + $self->{manager}->{output}->output_add(long_msg => ' ' . $vm); + } } sub run { my $self = shift; + my %filters = (); - - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{lvm}\E$/; + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{lvm}/; + $filters{name} = qr/$self->{vm_hostname}/; } - my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $not_installed = ''; - my $not_running = ''; - my $not_up2date = ''; + return if (!defined($result)); - foreach my $virtual (@$result) { - if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $virtual->{name} . "' not connected"); - } - next; - } - - if ($self->{skip_not_running} == 1 && - !centreon::esxd::common::is_running($virtual->{'runtime.powerState'}->val)) { - next; - } + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All VMTools are OK")); + } else { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("VMTools are OK")); + } + my %not_installed = (); + my %not_running = (); + my %not_up2date = (); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + nocheck_ps => 1, + multiple => $multiple) == 0); - my $tools_status = lc($virtual->{'summary.guest.toolsStatus'}->val); + next if (defined($self->{nopoweredon_skip}) && + !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + + my $tools_status = lc($entity_view->{'summary.guest.toolsStatus'}->val); if ($tools_status eq 'toolsnotinstalled') { - $not_installed .= ' [' . $virtual->{name} . ']'; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $not_installed{$entity_view->{name}} = 1; } elsif ($tools_status eq 'toolsnotrunning') { - $not_running .= ' [' . $virtual->{name} . ']'; - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + $not_running{$entity_view->{name}} = 1; } elsif ($tools_status eq 'toolsold') { - $not_up2date .= ' [' . $virtual->{name} . ']'; - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $not_up2date{$entity_view->{name}} = 1; } } - if ($not_installed ne '') { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "VMTools not installed on VM:" . $not_installed); + if (scalar(keys %not_up2date) > 0 && + !$self->{manager}->{output}->is_status(value => $self->{tools_notupd2date_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{tools_notupd2date_status}, + short_msg => sprintf('%d VM with VMTools not up-to-date', scalar(keys %not_up2date))); + $self->display_verbose(label => 'vmtools not up-to-date:', vms => \%not_up2date); } - if ($not_running ne '') { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "VMTools not running on VM:" . $not_running); + if (scalar(keys %not_running) > 0 && + !$self->{manager}->{output}->is_status(value => $self->{tools_notrunning_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{tools_notrunning_status}, + short_msg => sprintf('%d VM with VMTools not running', scalar(keys %not_running))); + $self->display_verbose(label => 'vmtools not running:', vms => \%not_running); } - if ($not_up2date ne '') { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "VMTools not up-to-date on VM:" . $not_up2date); + if (scalar(keys %not_installed) > 0 && + !$self->{manager}->{output}->is_status(value => $self->{tools_notupd2date_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{tools_notupd2date_status}, + short_msg => sprintf('%d VM with VMTools not installed', scalar(keys %not_installed))); + $self->display_verbose(label => 'vmtools not installed:', vms => \%not_installed); } - - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - " . $output_unknown; - $output_append = ". "; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - " . $output_critical; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - " . $output_warning; - } - if ($status == 0) { - $output .= $output_append . "VMTools are OK."; - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 1b268e7e2..5ff2ee8ea 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -406,9 +406,9 @@ sub is_connected { } sub is_running { - my ($power_state) = @_; + my (%options) = @_; - if ($power_state !~ /^poweredOn$/i) { + if ($options{power} !~ /^poweredOn$/i) { return 0; } return 1; @@ -428,19 +428,27 @@ sub datastore_state { } sub vm_state { - my ($obj_esxd, $vm, $connection_state, $power_state, $nocheck_ps) = @_; + my (%options) = @_; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{host_state_error}; + my $power_status = defined($options{powerstatus}) ? $options{powerstatus} : $options{connector}->{centreonesxd_config}->{vm_state_error}; - if ($connection_state !~ /^connected$/i) { - my $output = "VM '" . $vm . "' not connected. Current Connection State: '$connection_state'."; - $manager_display->{output}->output_add(severity => $obj_esxd->{centreonesxd_config}->{vm_state_error}, - short_msg => $output); + if ($options{state} !~ /^connected$/i) { + my $output = "VM '" . $options{hostname} . "' not connected. Current Connection State: '$options{state}'."; + if ($options{multiple} == 0 || + !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $manager_display->{output}->output_add(severity => $status, + short_msg => $output); + } return 0; } - if (!defined($nocheck_ps) && $power_state !~ /^poweredOn$/i) { - my $output = "VM '" . $vm . "' not running. Current Power State: '$power_state'."; - $manager_display->{output}->output_add(severity => $obj_esxd->{centreonesxd_config}->{vm_state_error}, - short_msg => $output); + if (!defined($options{nocheck_ps}) && $options{power} !~ /^poweredOn$/i) { + my $output = "VM '" . $options{hostname} . "' not running. Current Power State: '$options{power}'."; + if ($options{multiple} == 0 || + !$manager_display->{output}->is_status(value => $power_status, compare => 'ok', litteral => 1)) { + $manager_display->{output}->output_add(severity => $power_status, + short_msg => $output); + } return 0; } From a9ee878e3ce74743afc4c386160a8f60f00b7304 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Oct 2014 13:43:53 +0100 Subject: [PATCH 099/447] Refs #7246 Add system waiting for messages Dynamic connections --- .../vmware/src/centreon/esxd/connector.pm | 1 + .../src/centreon/script/centreonesxd.pm | 148 ++++++++++++++---- 2 files changed, 116 insertions(+), 33 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index d429ef04b..5a0b34c24 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -200,6 +200,7 @@ sub run { zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); zmq_setsockopt($backend, ZMQ_LINGER, 0); # we discard zmq_connect($backend, 'ipc://routing.ipc'); + centreon::esxd::common::response(token => 'READY', endpoint => $backend, stdout => ''); # Initialize poll set my @poll = ( diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 491e61759..655af1a0d 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -9,9 +9,9 @@ use VMware::VILib; use ZMQ::LibZMQ3; use ZMQ::Constants qw(:all); use File::Basename; +use Digest::MD5 qw(md5_hex); use POSIX ":sys_wait_h"; use JSON; -use Data::Dumper; use centreon::script; use centreon::esxd::common; use centreon::esxd::connector; @@ -28,32 +28,33 @@ use vars qw(%centreonesxd_config); my $VERSION = "1.6.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); -my @load_modules = ('centreon::esxd::cmdcountvmhost', - 'centreon::esxd::cmdcpuhost', - 'centreon::esxd::cmdcpuvm', - 'centreon::esxd::cmddatastoreio', - 'centreon::esxd::cmddatastoreiops', - 'centreon::esxd::cmddatastoreshost', - 'centreon::esxd::cmddatastoresnapshots', - 'centreon::esxd::cmddatastoresvm', - 'centreon::esxd::cmddatastoreusage', - 'centreon::esxd::cmdgetmap', - 'centreon::esxd::cmdhealthhost', - 'centreon::esxd::cmdlimitvm', - 'centreon::esxd::cmdlistdatastores', - 'centreon::esxd::cmdlistnichost', - 'centreon::esxd::cmdmemhost', - 'centreon::esxd::cmdmaintenancehost', - 'centreon::esxd::cmdmemvm', - 'centreon::esxd::cmdnethost', - 'centreon::esxd::cmdsnapshotvm', - 'centreon::esxd::cmdstatushost', - 'centreon::esxd::cmdswaphost', - 'centreon::esxd::cmdswapvm', - 'centreon::esxd::cmdthinprovisioningvm', - 'centreon::esxd::cmdtoolsvm', - 'centreon::esxd::cmduptimehost' - ); +my @load_modules = ( + 'centreon::esxd::cmdcountvmhost', + 'centreon::esxd::cmdcpuhost', + 'centreon::esxd::cmdcpuvm', + 'centreon::esxd::cmddatastoreio', + 'centreon::esxd::cmddatastoreiops', + 'centreon::esxd::cmddatastoreshost', + 'centreon::esxd::cmddatastoresnapshots', + 'centreon::esxd::cmddatastoresvm', + 'centreon::esxd::cmddatastoreusage', + 'centreon::esxd::cmdgetmap', + 'centreon::esxd::cmdhealthhost', + 'centreon::esxd::cmdlimitvm', + 'centreon::esxd::cmdlistdatastores', + 'centreon::esxd::cmdlistnichost', + 'centreon::esxd::cmdmemhost', + 'centreon::esxd::cmdmaintenancehost', + 'centreon::esxd::cmdmemvm', + 'centreon::esxd::cmdnethost', + 'centreon::esxd::cmdsnapshotvm', + 'centreon::esxd::cmdstatushost', + 'centreon::esxd::cmdswaphost', + 'centreon::esxd::cmdswapvm', + 'centreon::esxd::cmdthinprovisioningvm', + 'centreon::esxd::cmdtoolsvm', + 'centreon::esxd::cmduptimehost' +); sub new { my $class = shift; @@ -75,6 +76,7 @@ sub new { timeout_vsphere => 60, timeout => 60, timeout_kill => 30, + dynamic_timeout_kill => 86400, refresh_keeper_session => 15, port => 5700, datastore_state_error => 'UNKNOWN', @@ -238,7 +240,12 @@ sub verify_child_vsphere { if ($self->{stop} == 0) { $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "'???!! we relaunch it!!!"); - $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}); + if ($self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{dynamic} == 0) { + $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}, dynamic => 0); + } else { + $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' is dead. But we don't relaunch it (dynamic sub-process)"); + delete $self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}; + } } else { $self->{logger}->writeLogInfo("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' dead ???!!"); $self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{running} = 0; @@ -253,11 +260,70 @@ sub verify_child_vsphere { if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{running} == 1) { $count++; } + if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{dynamic} == 1 && + time() - $self->{centreonesxd_config}->{dynamic_timeout_kill} > $self->{centreonesxd_config}->{vsphere_server}->{$_}->{last_request}) { + $self->{logger}->writeLogError("Send TERM signal for process '" . $_ . "': too many times without requests. We clean it."); + kill('TERM', $self->{centreonesxd_config}->{vsphere_server}->{$_}->{pid}); + } } return $count; } +sub waiting_ready { + my ($self, %options) = @_; + + return 1 if ($self->{centreonesxd_config}->{vsphere_server}->{$options{container}}->{ready} == 1); + + my $time = time(); + # We wait 10 seconds + while ($self->{centreonesxd_config}->{vsphere_server}->{$options{container}}->{ready} == 0 && + time() - $time < 10) { + zmq_poll($self->{poll}, 5000); + } + + if ($self->{centreonesxd_config}->{vsphere_server}->{$options{container}}->{ready} == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "connector still not ready."); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return 0; + } + + return 1; +} + +sub request_dynamic { + my ($self, %options) = @_; + + if (!defined($options{result}->{vsphere_username}) || $options{result}->{vsphere_username} eq '' || + !defined($options{result}->{vsphere_password}) || $options{result}->{vsphere_password} eq '') { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Please set vsphere username or password"); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; + } + + my $container = md5_hex($options{result}->{vsphere_address} . $options{result}->{vsphere_username} . $options{result}->{vsphere_password}); + # Need to create fork + if (!defined($self->{centreonesxd_config}->{vsphere_server}->{$container})) { + $self->{centreonesxd_config}->{vsphere_server}->{$container} = { url => 'https://' . $options{result}->{vsphere_address} . '/sdk', + username => $options{result}->{vsphere_username}, + password => $options{result}->{vsphere_password}, + last_request => time() }; + $self->{logger}->writeLogError(sprintf("Dynamic creation: identity = %s [address: %s] [username: %s] [password: %s]", + $container, $options{result}->{vsphere_address}, $options{result}->{vsphere_username}, $options{result}->{vsphere_password})); + $centreonesxd->create_vsphere_child(vsphere_name => $container, dynamic => 1); + } + + return if ($self->waiting_ready(container => $container, manager => $options{manager}, + identity => $options{identity}) == 0); + + $self->{centreonesxd_config}->{vsphere_server}->{$container}->{last_request} = time(); + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + zmq_sendmsg($frontend, "server-" . $container, $flag); + zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); +} + sub request { my ($self, %options) = @_; @@ -289,6 +355,13 @@ sub request { centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } + + # Mode dynamic + if (defined($result->{vsphere_address}) && $result->{vsphere_address} ne '') { + $self->request_dynamic(result => $result, %options); + return ; + } + if (!defined($self->{centreonesxd_config}->{vsphere_server}->{$result->{container}})) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Unknown container name '$result->{container}'"); @@ -296,6 +369,9 @@ sub request { return ; } + return if ($self->waiting_ready(container => $result->{container}, manager => $options{manager}, + identity => $options{identity}) == 0); + $self->{counter_stats}->{$result->{container}}++; my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; zmq_sendmsg($frontend, "server-" . $result->{container}, $flag); @@ -335,12 +411,15 @@ sub router_event { if ($centreonesxd->{stop} != 0) { # We quit so we say we're leaving ;) $manager->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Daemon is restarting...'); + short_msg => 'Daemon is restarting/stopping...'); centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $identity); } elsif ($data =~ /^REQCLIENT\s+(.*)$/msi) { $centreonesxd->request(identity => $identity, data => $1, manager => $manager); } elsif ($data =~ /^RESPSERVER2\s+(.*)$/msi) { $centreonesxd->repserver(data => $1, manager => $manager); + } elsif ($data =~ /^READY/msi) { + $identity =~ /server-(.*)/; + $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$1}->{ready} = 1; } my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); @@ -353,6 +432,7 @@ sub create_vsphere_child { $self->{whoaim} = $options{vsphere_name}; $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 0; + $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{ready} = 0; $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); my $child_vpshere_pid = fork(); @@ -367,6 +447,8 @@ sub create_vsphere_child { } $self->{childs_vpshere_pid}->{$child_vpshere_pid} = $self->{whoaim}; $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 1; + $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{dynamic} = $options{dynamic}; + $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{pid} = $child_vpshere_pid; } sub run { @@ -392,19 +474,19 @@ sub run { foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { $centreonesxd->{counter_stats}->{$_} = 0; - $centreonesxd->create_vsphere_child(vsphere_name => $_); + $centreonesxd->create_vsphere_child(vsphere_name => $_, dynamic => 0); } $centreonesxd->{logger}->writeLogInfo("[Server accepting clients]"); # Initialize poll set - my @poll = ( + $centreonesxd->{poll} = [ { socket => $frontend, events => ZMQ_POLLIN, callback => \&router_event, }, - ); + ]; # Switch messages between sockets while (1) { @@ -419,7 +501,7 @@ sub run { } } - zmq_poll(\@poll, 5000); + zmq_poll($centreonesxd->{poll}, 5000); } } From c7a5416ab2162ace5df1e908bf823f6f978eb18c Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Oct 2014 14:21:57 +0100 Subject: [PATCH 100/447] Refs #7246 WIP --- .../centreon/esxd/cmdthinprovisioningvm.pm | 157 ++++++++++-------- 1 file changed, 90 insertions(+), 67 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm index ac61547e1..aee72d369 100644 --- a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'thinprovisioningvm'; bless $self, $class; @@ -22,95 +21,119 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($vm, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($vm) || $vm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm name"); + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); return 1; } + if (defined($options{arguments}->{thinprovisioning_status}) && $options{arguments}->{thinprovisioning_status} ne '') { + my ($entry, $status) = split /,/, $options{arguments}->{thinprovisioning_status}; + if ($entry !~ /^(notactive|active)$/) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Wrong thinprovisioning-status option. Can only be 'active' or 'noactive'. Not: '" . $entry . "'."); + return 1; + } + if ($options{manager}->{output}->is_litteral_status(status => $status) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Wrong thinprovisioning-status option. Not a good status: '" . $status . "'."); + return 1; + } + } return 0; } sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{on} = ((defined($_[2]) and $_[2] ne '') ? $_[2] : 0); - $self->{warn} = ((defined($_[3]) and $_[3] ne '') ? $_[3] : 0); - $self->{crit} = ((defined($_[4]) and $_[4] ne '') ? $_[4] : 0); - $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub display_verbose { + my ($self, %options) = @_; + + foreach my $vm (sort keys %{$options{vms}}) { + $self->{manager}->{output}->output_add(long_msg => $vm); + foreach my $disk (sort keys %{$options{vms}->{$vm}}) { + $self->{manager}->{output}->output_add(long_msg => ' ' . $disk); + } + } } sub run { my $self = shift; + my %filters = (); - - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{lvm}\E$/; + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{lvm}/; + $filters{name} = qr/$self->{vm_hostname}/; } - my @properties = ('name', 'config.hardware.device', 'runtime.connectionState'); + my @properties = ('name', 'config.hardware.device', 'runtime.connectionState', 'runtime.powerState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All thinprovisoning virtualdisks are ok.")); + } else { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("Thinprovisoning virtualdisks are ok.")); } - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - - foreach my $virtual (@$result) { - if (!centreon::esxd::common::is_connected($virtual->{'runtime.connectionState'}->val)) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $virtual->{name} . "' not connected"); - } - next; - } + my $disks_vm = {}; + my %maps_match = ('active' => { regexp => '^1$', output => 'VirtualDisks thinprovisioning actived' }, + 'notactive' => { regexp => '^(?!(1)$)', output => 'VirtualDisks thinprovisioning not actived' }); + my $num = 0; + my ($entry, $status); + if (defined($self->{thinprovisioning_status}) && $self->{thinprovisioning_status} ne '') { + ($entry, $status) = split /,/, $self->{thinprovisioning_status}; + } - my $output_disk = ''; - foreach (@{$virtual->{'config.hardware.device'}}) { - if ($_->isa('VirtualDisk')) { - if ($self->{on} == 1 && $self->{warn} == 1 && $_->backing->thinProvisioned == 1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $output_disk .= ' [' . $_->backing->fileName . ']'; - } - if ($self->{on} == 1 && $self->{crit} == 1 && $_->backing->thinProvisioned == 1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $output_disk .= ' [' . $_->backing->fileName . ']'; - } - if ($self->{on} == 0 && $self->{warn} == 1 && $_->backing->thinProvisioned != 1) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $output_disk .= ' [' . $_->backing->fileName . ']'; - } - if ($self->{on} == 0 && $self->{crit} == 1 && $_->backing->thinProvisioned != 1) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $output_disk .= ' [' . $_->backing->fileName . ']'; - } - } - } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + nocheck_ps => 1, + multiple => $multiple) == 0); + + next if (defined($self->{nopoweredon_skip}) && + !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); - if ($output_disk ne '') { - centreon::esxd::common::output_add(\$output, \$output_append, ", ", - 'VM ' . $virtual->{name} . ':' . $output_disk); + foreach (@{$entity_view->{'config.hardware.device'}}) { + if ($_->isa('VirtualDisk')) { + if (defined($entry) && $_->backing->thinProvisioned =~ /$maps_match{$entry}->{regexp}/) { + $num++; + $disks_vm->{$entity_view->{name}} = {} if (!defined($disks_vm->{$entity_view->{name}})); + $disks_vm->{$entity_view->{name}}->{$_->backing->fileName} = 1; + } + } } } - if ($output ne "" && $self->{on} == 1) { - $output = "VirtualDisks thinprovisioning actived - $output."; - } elsif ($output ne "" && $self->{on} == 0) { - $output = "VirtualDisks thinprovisioning not actived - $output."; + if ($num > 0) { + $self->{manager}->{output}->output_add(severity => $status, + short_msg => sprintf('%d %s', $num, $maps_match{$entry}->{output})); + $self->display_verbose(vms => $disks_vm); } - if ($status == 0) { - $output .= $output_append . "Thinprovisoning virtualdisks are ok."; - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; From c38671738c68028dbb3fd67c9aedc87a6ca4952b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Oct 2014 16:04:05 +0100 Subject: [PATCH 101/447] Refs #7246 WIP (near the end) --- connectors/vmware/centreon_esx_client.pl | 22 -- .../src/centreon/esxd/cmddatastoreio.pm | 145 +++++++---- .../src/centreon/esxd/cmddatastoreiops.pm | 213 ++++++++-------- .../src/centreon/esxd/cmddatastoreusage.pm | 230 ++++++++---------- connectors/vmware/src/centreon/esxd/common.pm | 22 +- 5 files changed, 323 insertions(+), 309 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index de3dae11a..66cadc59d 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -113,15 +113,6 @@ sub print_usage () { print " --vsphere vsphere name (default: none)\n"; print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; - print "'datastore-usage':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold (default 80)\n"; - print " -c (--critical) Critical Threshold (default 90)\n"; - print " --units Threshold units: %, MB (default is MB)\n"; - print " --free Threshold is for free size\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; - print "\n"; print "'datastore-iops':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold (default none)\n"; @@ -130,11 +121,6 @@ sub print_usage () { print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; print " --details-value Only display VMs with iops higher than the following value (permits to see VMs with high values) (default 50)\n"; print "\n"; - print "'datastore-io':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in kBps (default none)\n"; - print " -c (--critical) Critical Threshold in kBps (default none)\n"; - print "\n"; print "'datastore-snapshots':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; @@ -156,14 +142,6 @@ sub print_usage () { print " -w (--warning) Warning Threshold in IOPS (default none)\n"; print " -c (--critical) Critical Threshold in IOPS (default none)\n"; print "\n"; - print "'thinprovisioningvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --on Warn or critical if thinprovisioning set\n"; - print " --crit Critical\n"; - print " --warn Warn\n"; - print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; - print "\n"; } sub print_help () { diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm index 5b7e3e73e..71550a0bc 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm @@ -9,8 +9,7 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-io'; + $self->{commandName} = 'datastoreio'; bless $self, $class; return $self; @@ -22,79 +21,131 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($ds, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name"); + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); return 1; } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : ''); - $self->{crit} = (defined($_[2]) ? $_[2] : ''); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('summary.name' => $self->{ds}); - my @properties = ('summary.name', 'summary.accessible'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->{'summary.accessible'}) == 0); - + my %filters = (); + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datastore_name}/; + } + my @properties = ('summary.name', 'summary.accessible'); + + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + return if (!defined($result)); + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])); - - my $status = 0; # OK - my $output = ''; - if ((defined($self->{warn}) && $self->{warn} ne "") && - ($read_counter >= $self->{warn} || $write_counter >= $self->{warn})) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if (scalar(@$result) > 1) { + $multiple = 1; } - if ((defined($self->{crit}) && $self->{crit} ne "") && - ($read_counter >= $self->{crit} || $write_counter >= $self->{crit})) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All datastore rates are ok")); } + + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $entity_view->{'summary.name'}, + state => $entity_view->{'summary.accessible'}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + # in KBps + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; - $output = "Rate of reading data : " . centreon::esxd::common::simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . centreon::esxd::common::simplify_number($write_counter / 1024 * 8) . " Mb/s"; - $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + my ($read_value, $read_unit) = $self->{manager}->{perfdata}->change_bytes(value => $read_counter); + my ($write_value, $write_unit) = $self->{manager}->{perfdata}->change_bytes(value => $write_counter); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Rate of reading data: %s Rate of writing data: %s", + $entity_view->{'summary.name'}, + $read_value . " " . $read_unit . "/s", + $write_value . " " . $write_unit . "/s")); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Rate of reading data: %s Rate of writing data: %s", + $entity_view->{'summary.name'}, + $read_value . " " . $read_unit . "/s", + $write_value . " " . $write_unit . "/s")); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{'summary.name'} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'read_rate' . $extra_label, unit => 'B/s', + value => $read_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'write_rate' . $extra_label, unit => 'B/s', + value => $write_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm index 37eeabd2b..cae46986a 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm @@ -9,8 +9,7 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-iops'; + $self->{commandName} = 'datastoreiops'; bless $self, $class; return $self; @@ -22,87 +21,87 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($ds, $filter, $warn, $crit, $details_value) = @_; + my ($self, %options) = @_; - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name"); + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); return 1; } - if (defined($details_value) && $details_value ne "" && $details_value !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: details-value must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) ? $_[2] : ''); - $self->{crit} = (defined($_[3]) ? $_[3] : ''); - $self->{details_value} = (defined($_[4]) ? $_[4] : 50); - $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $perfdata = ''; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } my %filters = (); - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{ds}\E$/; + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{ds}/; + $filters{name} = qr/$self->{datastore_name}/; } - my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastore IOPS counters are ok")); } #my %uuid_list = (); my %disk_name = (); my %datastore_lun = (); foreach (@$result) { - if (!centreon::esxd::common::is_accessible($_->{'summary.accessible'})) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $_->{'summary.name'} . "' not accessible. Can be disconnected"); - } - next; - } + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $_->{'summary.name'}, + state => $_->{'summary.accessible'}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; @@ -133,15 +132,13 @@ sub run { @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); - if (!defined($result2)) { - return ; - } + return if (!defined($result2)); # Remove disconnected or not running vm my %ref_ids_vm = (); for(my $i = $#{$result2}; $i >= 0; --$i) { - if (!centreon::esxd::common::is_connected(${$result2}[$i]->{'runtime.connectionState'}->val) || - !centreon::esxd::common::is_running(${$result2}[$i]->{'runtime.powerState'}->val)) { + if (!centreon::esxd::common::is_connected(state => ${$result2}[$i]->{'runtime.connectionState'}->val) || + !centreon::esxd::common::is_running(power => ${$result2}[$i]->{'runtime.powerState'}->val)) { splice @$result2, $i, 1; next; } @@ -153,7 +150,8 @@ sub run { $result2, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{obj_esxd}->{perfcounter_speriod}, 1, 1); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); @@ -161,9 +159,7 @@ sub run { my ($vm_id, $id, $disk_name) = split(/:/); # RDM Disk. We skip. Don't know how to manage it right now. - if (!defined($disk_name{$disk_name})) { - next; - } + next if (!defined($disk_name{$disk_name})); my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{obj_esxd}->{perfcounter_speriod})); $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; @@ -178,62 +174,65 @@ sub run { my $total_read_counter = $datastore_lun{$_}{'disk.numberRead.summation'}; my $total_write_counter = $datastore_lun{$_}{'disk.numberWrite.summation'}; - if (defined($self->{crit}) && $self->{crit} ne "" && ($total_read_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$total_read_counter' read iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberRead.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($total_read_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$total_read_counter' read on '" . $_ . "'" . $self->vm_iops_details('disk.numberRead.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read iops on '%s'", + $total_read_counter, $_)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' read iops on '%s'", + $total_read_counter, $_)); + $self->vm_iops_details(label => 'disk.numberRead.summation', + type => 'read', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm); } - if (defined($self->{crit}) && $self->{crit} ne "" && ($total_write_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$total_write_counter' write iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberWrite.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($total_write_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$total_write_counter' write iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberWrite.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write iops on '%s'", + $total_write_counter, $_)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' write iops on '%s'", + $total_write_counter, $_)); + $self->vm_iops_details(label => 'disk.numberWrite.summation', + type => 'write', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm) } - if ($self->{filter} == 1) { - $perfdata .= " 'riops_" . $_ . "'=" . $total_read_counter . "iops;$self->{warn};$self->{crit};0; 'wiops_" . $_ . "'=" . $total_write_counter . "iops;$self->{warn};$self->{crit};0;"; - } else { - $perfdata .= " 'riops=" . $total_read_counter . "iops;$self->{warn};$self->{crit};0; wiops=" . $total_write_counter . "iops;$self->{warn};$self->{crit};0;"; - } + my $extra_label = ''; + $extra_label = '_' . $_ if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'riops' . $extra_label, unit => 'iops', + value => $total_read_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'wiops' . $extra_label, unit => 'iops', + value => $total_write_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); } - - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $output_warning"; - } - if ($status == 0) { - $output = "All Datastore IOPS counters are ok"; - } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } sub vm_iops_details { - my ($self, $label, $ds_details, $ref_ids_vm) = @_; - my $details = ''; + my ($self, %options) = @_; - foreach my $value (keys %$ds_details) { - # Dont need to display vm with iops < 1 - if ($value =~ /^vm.*?$label$/ && $ds_details->{$value} >= $self->{details_value}) { - my ($vm_ids) = split(/_/, $value); - $details .= " ['" . $ref_ids_vm->{$vm_ids} . "' " . $ds_details->{$value} . ']'; + $self->{manager}->{output}->output_add(long_msg => sprintf(" VM IOPs details: ")); + my $num = 0; + foreach my $value (keys %{$options{detail}}) { + # display only for high iops + if ($value =~ /^vm.*?$options{label}$/ && $options{detail}->{$value} >= $self->{detail_iops_min}) { + my ($vm_id) = split(/_/, $value); + $num++; + $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s' %s iops", $options{ref_vm}->{$vm_id}, $options{detail}->{$value})); } } - return $details; + if ($num == 0) { + $self->{manager}->{output}->output_add(long_msg => sprintf(" no vm with iops >= %s", $self->{detail_iops_min})); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm index fd328f23c..e2e3bf440 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm @@ -9,8 +9,7 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-usage'; + $self->{commandName} = 'datastoreusage'; bless $self, $class; return $self; @@ -22,162 +21,145 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($ds, $filter, $warn, $crit, $free, $units) = @_; + my ($self, %options) = @_; - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name."); + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number."); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number."); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && (!defined($free) || $free != 1) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold."); - return 1; + if (!defined($options{arguments}->{units}) || $options{arguments}->{units} !~ /^(%|B)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong units option '" . (defined($options{arguments}->{units}) ? $options{arguments}->{units} : 'null') . "'."); + $self->{output}->option_exit(); } - if (defined($warn) && defined($crit) && defined($free) && $free == 1 && $warn < $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be higher than crit threshold."); - return 1; - } - if (defined($units) && ($units !~ /^(%|MB)/)) { - $self->{logger}->writeLogError("ARGS error: units should be '%' or 'MB'."); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{free} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) ? $_[2] : (($self->{free} == 1) ? 20 : 80)); - $self->{crit} = (defined($_[3]) ? $_[3] : (($self->{free} == 1) ? 10 : 90)); - $self->{units} = (defined($_[5])) ? $_[5] : '%'; - $self->{skip_errors} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = (); - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{ds}\E$/; + my %filters = (); + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{ds}/; + $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastore usages are ok")); } - my $status = 0; # OK - my $output = ""; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $output_ok_unit = ''; - my $perfdata = ''; - my ($warn_threshold, $crit_threshold); - my ($pctwarn_threshold, $pctcrit_threshold) = ($self->{warn}, $self->{crit}); - - if ($self->{units} eq '%' && $self->{free} == 1) { - $pctwarn_threshold = 100 - $self->{warn}; - $pctcrit_threshold = 100 - $self->{crit}; - } - - foreach my $ds (@$result) { - if (!centreon::esxd::common::is_accessible($ds->summary->accessible)) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $ds->summary->name . "' not accessible. Can be disconnected"); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $entity_view->summary->name, + state => $entity_view->summary->accessible, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + + # capacity 0... + if ($entity_view->summary->capacity <= 0) { + if ($multiple == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("datastore size is 0")); } next; } - - # capacity 0... - next if ($ds->summary->capacity <= 0); - my $dsName = $ds->summary->name; - my $capacity = $ds->summary->capacity; - my $free = $ds->summary->freeSpace; + # in Bytes + my $name_storage = $entity_view->summary->name; + my $total_size = $entity_view->summary->capacity; + my $total_free = $entity_view->summary->freeSpace; + my $total_used = $total_size - $total_free; + my $prct_used = $total_used * 100 / $total_size; + my $prct_free = 100 - $prct_used; - if ($self->{units} eq 'MB' && $self->{free} == 1) { - $warn_threshold = $capacity - ($self->{warn} * 1024 * 1024); - $crit_threshold = $capacity - ($self->{crit} * 1024 * 1024); - } elsif ($self->{units} eq 'MB' && $self->{free} == 0) { - $warn_threshold = $self->{warn} * 1024 * 1024; - $crit_threshold = $self->{crit} * 1024 * 1024; - } else { - $warn_threshold = ($capacity * $pctwarn_threshold) / 100; - $crit_threshold = ($capacity * $pctcrit_threshold) / 100; - } - - my $pct = ($capacity - $free) / $capacity * 100; + my ($exit, $threshold_value); + $threshold_value = $total_used; + $threshold_value = $total_free if (defined($self->{free})); + if ($self->{units} eq '%') { + $threshold_value = $prct_used; + $threshold_value = $prct_free if (defined($self->{free})); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; - my $sizeD = $capacity / 1024 / 1024 / 1024; + my ($total_size_value, $total_size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_size); + my ($total_used_value, $total_used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_used); + my ($total_free_value, $total_free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_free); - $output_ok_unit = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"; - - if ($self->{units} eq '%' && $pct >= $pctcrit_threshold) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif ($self->{units} eq '%' && $pct >= $pctwarn_threshold) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } elsif ($self->{units} eq 'MB' && ($capacity - $free) >= $crit_threshold) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif ($self->{units} eq 'MB' && ($capacity - $free) >= $warn_threshold) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } + $self->{manager}->{output}->output_add(long_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $prct_used, + $total_free_value . " " . $total_free_unit, $prct_free)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $prct_used, + $total_free_value . " " . $total_free_unit, $prct_free)); + } - if ($self->{filter} == 1) { - $perfdata .= " 'used_" . $dsName . "'=".($capacity - $free)."o;" . $warn_threshold . ";" . $crit_threshold . ";0;" . $capacity; - } else { - $perfdata .= " used=".($capacity - $free)."o;" . $warn_threshold . ";" . $crit_threshold . ";0;" . $capacity; + my $label = 'used'; + my $value_perf = $total_used; + if (defined($self->{free})) { + $label = 'free'; + $value_perf = $total_free; } - } - - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Datastore(s): $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Datastore(s): $output_warning"; - } - if ($status == 0) { - if ($self->{filter} == 1) { - $output .= $output_append . "All Datastore usages are ok"; - } else { - $output .= $output_append . $output_ok_unit; + my $extra_label = ''; + $extra_label = '_' . $name_storage if ($multiple == 1); + my %total_options = (); + if ($self->{units} eq '%') { + $total_options{total} = $total_size; + $total_options{cast_int} = 1; } + $self->{manager}->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), + min => 0, max => $total_size); } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 5ff2ee8ea..93fabc79f 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -388,18 +388,18 @@ sub performance_errors { } sub is_accessible { - my ($accessible) = @_; + my (%options) = @_; - if ($accessible !~ /^true|1$/) { + if ($options{accessible} !~ /^true|1$/) { return 0; } return 1; } sub is_connected { - my ($connection_state) = @_; + my (%options) = @_; - if ($connection_state !~ /^connected$/i) { + if ($options{state} !~ /^connected$/i) { return 0; } return 1; @@ -415,12 +415,16 @@ sub is_running { } sub datastore_state { - my ($obj_esxd, $ds, $accessible) = @_; + my (%options) = @_; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{datastore_state_error}; - if ($accessible !~ /^true|1$/) { - my $output = "Datastore '" . $ds . "' not accessible. Can be disconnected."; - my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{datastore_state_error}); - $obj_esxd->print_response(get_status($status) . "|$output\n"); + if ($options{state} !~ /^true|1$/) { + my $output = "Datastore '" . $options{name} . "' not accessible. Current connection state: '$options{state}'."; + if ($options{multiple} == 0 || + !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $manager_display->{output}->output_add(severity => $status, + short_msg => $output); + } return 0; } From 1b5de2d36031b54261b65978048c833bd655caf0 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Oct 2014 17:32:54 +0100 Subject: [PATCH 102/447] Refs #7246 WIP (only one todo) --- connectors/vmware/centreon_esx_client.pl | 20 -- .../src/centreon/esxd/cmddatastorehost.pm | 211 ++++++++++++++++ .../src/centreon/esxd/cmddatastoreshost.pm | 180 -------------- .../src/centreon/esxd/cmddatastoresvm.pm | 171 ------------- .../src/centreon/esxd/cmddatastorevm.pm | 227 ++++++++++++++++++ .../src/centreon/script/centreonesxd.pm | 4 +- 6 files changed, 440 insertions(+), 373 deletions(-) create mode 100644 connectors/vmware/src/centreon/esxd/cmddatastorehost.pm delete mode 100644 connectors/vmware/src/centreon/esxd/cmddatastoreshost.pm delete mode 100644 connectors/vmware/src/centreon/esxd/cmddatastoresvm.pm create mode 100644 connectors/vmware/src/centreon/esxd/cmddatastorevm.pm diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index 66cadc59d..72b66a3c0 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -113,14 +113,6 @@ sub print_usage () { print " --vsphere vsphere name (default: none)\n"; print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; - print "'datastore-iops':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold (default none)\n"; - print " -c (--critical) Critical Threshold (default none)\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; - print " --details-value Only display VMs with iops higher than the following value (permits to see VMs with high values) (default 50)\n"; - print "\n"; print "'datastore-snapshots':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; @@ -130,18 +122,6 @@ sub print_usage () { print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; print " --skip-errors Status OK if not enough permissions or others errors (when you checks multiples)\n"; print "\n"; - print "'datastoreshost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " -w (--warning) Warning Threshold in ms (latency) (default none)\n"; - print " -c (--critical) Critical Threshold in ms (latency) (default none)\n"; - print " --datastore Datastores to check (can use a regexp with --filter)\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print "\n"; - print "'datastoresvm':\n"; - print " --vm VM to check (required)\n"; - print " -w (--warning) Warning Threshold in IOPS (default none)\n"; - print " -c (--critical) Critical Threshold in IOPS (default none)\n"; - print "\n"; } sub print_help () { diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm b/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm new file mode 100644 index 000000000..e9dfe7931 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm @@ -0,0 +1,211 @@ + +package centreon::esxd::cmddatastorehost; + +use strict; +use warnings; +use File::Basename; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'datastorehost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); + return ; + } + + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'config.fileSystemVolume.mountInfo', 'runtime.connectionState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + + my %uuid_list = (); + #my %disk_name = (); + my $query_perfs = []; + my $ds_regexp; + if (defined($self->{datastore_name}) && !defined($self->{filter_datastore})) { + $ds_regexp = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $ds_regexp = qr/.*/; + } else { + $ds_regexp = qr/$self->{datastore_name}/; + } + + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + + my $instances = []; + foreach (@{$entity_view->{'config.fileSystemVolume.mountInfo'}}) { + if ($_->volume->isa('HostVmfsVolume')) { + next if ($_->volume->name !~ /$ds_regexp/); + + $uuid_list{$_->volume->uuid} = $_->volume->name; + push @$instances, $_->volume->uuid; + # Not need. We are on Datastore level (not LUN level) + #foreach my $extent (@{$_->volume->extent}) { + # $disk_name{$extent->diskName} = $_->volume->name; + #} + } + if ($_->volume->isa('HostNasVolume')) { + next if ($_->volume->name !~ /$ds_regexp/); + + $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; + push @$instances, basename($_->mountInfo->path); + } + } + + if (scalar(@$instances) > 0) { + push @$query_perfs, { + entity => $entity_view, + metrics => [ + {label => 'datastore.totalReadLatency.average', instances => $instances}, + {label => 'datastore.totalWriteLatency.average', instances => $instances} + ] + }; + } + } + + if (scalar(@$query_perfs) == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't get a single datastore."); + return ; + } + + # Vsphere >= 4.1 + # You get counters even if datastore is disconnect... + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + undef, + $query_perfs, + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastore latencies are ok")); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + my $checked = {}; + foreach (keys %{$values->{$entity_value}}) { + my ($id, $uuid) = split /:/; + next if (defined($checked->{$uuid})); + $checked->{$uuid} = 1; + + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid}[0])); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid}[0])); + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read on '%s' is %s ms", + $entity_view->{name}, $uuid_list{$uuid}, $read_counter)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' read on '%s' is %s ms", + $entity_view->{name}, $uuid_list{$uuid}, $read_counter)); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write on '%s' is %s ms", + $entity_view->{name}, $uuid_list{$uuid}, $write_counter)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' write on '%s' is %s ms", + $entity_view->{name}, $uuid_list{$uuid}, $write_counter)); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'trl' . $extra_label . '_' . $uuid_list{$uuid}, unit => 'ms', + value => $read_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'twl' . $extra_label . '_' . $uuid_list{$uuid}, unit => 'ms', + value => $write_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreshost.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreshost.pm deleted file mode 100644 index 042853f73..000000000 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreshost.pm +++ /dev/null @@ -1,180 +0,0 @@ - -package centreon::esxd::cmddatastoreshost; - -use strict; -use warnings; -use File::Basename; -use centreon::esxd::common; - -sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastoreshost'; - - bless $self, $class; - return $self; -} - -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - -sub checkArgs { - my $self = shift; - my ($lhost, $filter, $warn, $crit) = @_; - - if (!defined($lhost) || $lhost eq "") { - $self->{logger}->writeLogError("ARGS error: need host name"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; - } - return 0; -} - -sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) ? $_[2] : ''); - $self->{crit} = (defined($_[3]) ? $_[3] : ''); - $self->{ds} = (defined($_[4]) ? $_[4] : ''); -} - -sub run { - my $self = shift; - my $filter_ok = 0; - - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $self->{lhost}); - my @properties = ('config.fileSystemVolume.mountInfo', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - - my %uuid_list = (); - #my %disk_name = (); - my $instances = []; - if ($self->{ds} eq '') { - $instances = ['*']; - } - foreach (@{$$result[0]->{'config.fileSystemVolume.mountInfo'}}) { - if ($_->volume->isa('HostVmfsVolume')) { - if ($self->{ds} ne '') { - if ($self->{filter} == 0 && $_->volume->name !~ /^\Q$self->{ds}\E$/) { - next; - } elsif ($self->{filter} == 1 && $_->volume->name !~ /$self->{ds}/) { - next; - } - } - - $filter_ok = 1; - $uuid_list{$_->volume->uuid} = $_->volume->name; - push @$instances, $_->volume->uuid; - # Not need. We are on Datastore level (not LUN level) - #foreach my $extent (@{$_->volume->extent}) { - # $disk_name{$extent->diskName} = $_->volume->name; - #} - } - if ($_->volume->isa('HostNasVolume')) { - if ($self->{ds} ne '') { - if ($self->{filter} == 0 && $_->volume->name !~ /^\Q$self->{ds}\E$/) { - next; - } elsif ($self->{filter} == 1 && $_->volume->name !~ /$self->{ds}/) { - next; - } - } - - $filter_ok = 1; - $uuid_list{basename($_->mountInfo->path)} = $_->volume->name; - push @$instances, basename($_->mountInfo->path); - } - } - - if ($self->{ds} ne '' and $filter_ok == 0) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status). "|Can't get a datastore with the filter '$self->{ds}'.\n"); - return ; - } - - # Vsphere >= 4.1 - # You get counters even if datastore is disconnect... - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $result, - [{'label' => 'datastore.totalReadLatency.average', 'instances' => $instances}, - {'label' => 'datastore.totalWriteLatency.average', 'instances' => $instances}], - $self->{obj_esxd}->{perfcounter_speriod}); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $perfdata = ''; - foreach (keys %uuid_list) { - if (defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}) and - defined($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_})) { - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $_}[0])); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $_}[0])); - if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "read on '" . $uuid_list{$_} . "' is $read_counter ms"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "write on '" . $uuid_list{$_} . "' is $write_counter ms"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - - $perfdata .= " 'trl_" . $uuid_list{$_} . "'=" . $read_counter . "ms 'twl_" . $uuid_list{$_} . "'=" . $write_counter . 'ms'; - } - } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Latency counter: $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Latency counter: $output_warning"; - } - if ($status == 0) { - $output = "All Datastore latency counters are ok"; - } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); -} - -1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoresvm.pm b/connectors/vmware/src/centreon/esxd/cmddatastoresvm.pm deleted file mode 100644 index a5aba1c87..000000000 --- a/connectors/vmware/src/centreon/esxd/cmddatastoresvm.pm +++ /dev/null @@ -1,171 +0,0 @@ - -package centreon::esxd::cmddatastoresvm; - -use strict; -use warnings; -use centreon::esxd::common; - -sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastoresvm'; - - bless $self, $class; - return $self; -} - -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - -sub checkArgs { - my $self = shift; - my ($lvm, $warn, $crit) = @_; - - if (!defined($lvm) || $lvm eq "") { - $self->{logger}->writeLogError("ARGS error: need vm name"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; - } - return 0; -} - -sub initArgs { - my $self = shift; - $self->{lvm} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : ''); - $self->{crit} = (defined($_[2]) ? $_[2] : ''); -} - -sub run { - my $self = shift; - - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('name' => $self->{lvm}); - my @properties = ('datastore', 'runtime.connectionState', 'runtime.powerState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - return if (centreon::esxd::common::vm_state($self->{obj_esxd}, $self->{lvm}, - $$result[0]->{'runtime.connectionState'}->val, - $$result[0]->{'runtime.powerState'}->val) == 0); - - my @ds_array = (); - foreach my $entity_view (@$result) { - if (defined $entity_view->datastore) { - @ds_array = (@ds_array, @{$entity_view->datastore}); - } - } - @properties = ('info'); - my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties); - if (!defined($result2)) { - return ; - } - - #my %uuid_list = (); - my %disk_name = (); - my %datastore_lun = (); - foreach (@$result2) { - if ($_->info->isa('VmfsDatastoreInfo')) { - #$uuid_list{$_->volume->uuid} = $_->volume->name; - # Not need. We are on Datastore level (not LUN level) - foreach my $extent (@{$_->info->vmfs->extent}) { - $disk_name{$extent->diskName} = $_->info->vmfs->name; - if (!defined($datastore_lun{$_->info->vmfs->name})) { - %{$datastore_lun{$_->info->vmfs->name}} = ('disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0); - } - } - } - #if ($_->info->isa('NasDatastoreInfo')) { - # Zero disk Info - #} - } - - # Vsphere >= 4.1 - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $result, - [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, - {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{obj_esxd}->{perfcounter_speriod}); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - foreach (keys %$values) { - my ($id, $disk_name) = split(/:/); - - # RDM Disk. We skip. Don't know how to manage it right now. - if (!defined($disk_name{$disk_name})) { - next; - } - - $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$_}[0]; - } - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $perfdata = ''; - foreach (keys %datastore_lun) { - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); - - if (defined($self->{crit}) && $self->{crit} ne "" && ($read_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "read iops on '" . $_ . "' is $read_counter"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($read_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "read iops on '" . $_ . "' is $read_counter"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if (defined($self->{crit}) && $self->{crit} ne "" && ($write_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "write iops on '" . $_ . "' is $write_counter"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($write_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "write iops '" . $_ . "' is $write_counter"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - - $perfdata .= " 'riops_" . $_ . "'=" . $read_counter . "iops 'wiops_" . $_ . "'=" . $write_counter . 'iops'; - } - - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $output_warning"; - } - if ($status == 0) { - $output = "All Datastore IOPS counters are ok"; - } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); -} - -1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm new file mode 100644 index 000000000..04d662496 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm @@ -0,0 +1,227 @@ + +package centreon::esxd::cmddatastorevm; + +use strict; +use warnings; +use centreon::esxd::common; +use File::Basename; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'datastorevm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + if (defined($options{arguments}->{nopoweredon_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); + return 1; + } + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); + return ; + } + + my %filters = (); + my $multiple = 0; + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{vm_hostname}/; + } + my @properties = ('name', 'datastore', 'runtime.connectionState', 'runtime.powerState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + my $ds_regexp; + if (defined($self->{datastore_name}) && !defined($self->{filter_datastore})) { + $ds_regexp = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $ds_regexp = qr/.*/; + } else { + $ds_regexp = qr/$self->{datastore_name}/; + } + + my $mapped_datastore = {}; + my @ds_array = (); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + power => $entity_view->{'runtime.powerState'}->val, + status => $self->{disconnect_status}, + powerstatus => $self->{nopoweredon_status}, + multiple => $multiple) == 0); + if (defined($entity_view->datastore)) { + foreach (@{$entity_view->datastore}) { + if (!defined($mapped_datastore->{$_->value})) { + push @ds_array, $_; + $mapped_datastore->{$_->value} = 1; + } + } + } + } + + @properties = ('info'); + my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties); + return if (!defined($result2)); + + #my %uuid_list = (); + my %disk_name = (); + my %datastore_lun = (); + foreach (@$result2) { + if ($_->info->isa('VmfsDatastoreInfo')) { + #$uuid_list{$_->volume->uuid} = $_->volume->name; + # Not need. We are on Datastore level (not LUN level) + foreach my $extent (@{$_->info->vmfs->extent}) { + $disk_name{$extent->diskName} = $_->info->vmfs->name; + } + } + #if ($_->info->isa('NasDatastoreInfo')) { + # Zero disk Info + #} + } + + # Vsphere >= 4.1 + # We don't filter. To filter we'll need to get disk from vms + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $result, + [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, + {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastore IOPS counters are ok")); + my $finded = 0; + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0 && + centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $finded |= 1; + my %datastore_lun = (); + foreach (keys %{$values->{$entity_value}}) { + my ($id, $disk_name) = split /:/; + + # RDM Disk. We skip. Don't know how to manage it right now. + next if (!defined($disk_name{$disk_name})); + # We skip datastore not filtered + next if ($disk_name{$disk_name} !~ /$ds_regexp/); + $datastore_lun{$disk_name{$disk_name}} = { 'disk.numberRead.summation' => 0, + 'disk.numberWrite.summation' => 0 } if (!defined($datastore_lun{$disk_name{$disk_name}})); + $datastore_lun{$disk_name{$disk_name}}->{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}[0]; + } + + foreach (sort keys %datastore_lun) { + $finded |= 2; + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read iops on '%s' is %s", + $entity_view->{name}, $_, $read_counter)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' read iops on '%s' is %s", + $entity_view->{name}, $_, $read_counter)); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write iops on '%s' is %s", + $entity_view->{name}, $_, $write_counter)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' write iops on '%s' is %s", + $entity_view->{name}, $_, $write_counter)); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'riops' . $extra_label . '_' . $_, unit => 'iops', + value => $read_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'wiops' . $extra_label . '_' . $_, unit => 'iops', + value => $write_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + } + + if (($finded & 2) == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't get a single datastore."); + } +} + +1; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 655af1a0d..3076839fc 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -34,9 +34,9 @@ my @load_modules = ( 'centreon::esxd::cmdcpuvm', 'centreon::esxd::cmddatastoreio', 'centreon::esxd::cmddatastoreiops', - 'centreon::esxd::cmddatastoreshost', + 'centreon::esxd::cmddatastorehost', 'centreon::esxd::cmddatastoresnapshots', - 'centreon::esxd::cmddatastoresvm', + 'centreon::esxd::cmddatastorevm', 'centreon::esxd::cmddatastoreusage', 'centreon::esxd::cmdgetmap', 'centreon::esxd::cmdhealthhost', From 68c7a186b990c352fd5de1ea84c71dfc68324bcb Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Oct 2014 10:28:20 +0100 Subject: [PATCH 103/447] Fix #7246 --- .../src/centreon/esxd/cmddatastoresnapshot.pm | 163 +++++++++++++ .../centreon/esxd/cmddatastoresnapshots.pm | 224 ------------------ .../src/centreon/script/centreonesxd.pm | 2 +- 3 files changed, 164 insertions(+), 225 deletions(-) create mode 100644 connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm delete mode 100644 connectors/vmware/src/centreon/esxd/cmddatastoresnapshots.pm diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm new file mode 100644 index 000000000..d1c6aad30 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm @@ -0,0 +1,163 @@ + +package centreon::esxd::cmddatastoresnapshot; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'datastoresnapshot'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + foreach my $label (('warning_total', 'critical_total', 'warning_snapshot', 'critical_snapshot')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_total', 'critical_total', 'warning_snapshot', 'critical_snapshot')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datastore_name}/; + } + my @properties = ('summary.accessible', 'summary.name', 'browser'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + + my @ds_array = (); + my %ds_names = (); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $entity_view->{'summary.name'}, + state => $entity_view->{'summary.accessible'}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + if (defined($entity_view->browser)) { + push @ds_array, $entity_view->browser; + $ds_names{$entity_view->{mo_ref}->{value}} = $entity_view->{'summary.name'}; + } + } + + @properties = (); + my $result2; + return if (!($result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties))); + + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All snapshot sizes are ok")); + foreach my $browse_ds (@$result2) { + my $dsName; + my $tmp_name = $browse_ds->{mo_ref}->{value}; + $tmp_name =~ s/^datastoreBrowser-//i; + $dsName = $ds_names{$tmp_name}; + + $self->{manager}->{output}->output_add(long_msg => "Checking datastore '$dsName':"); + my ($snapshots, $msg) = centreon::esxd::common::search_in_datastore($self->{obj_esxd}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); + if (!defined($snapshots)) { + $msg =~ s/\n/ /g; + if ($msg =~ /NoPermissionFault/i) { + $msg = "Not enough permissions"; + } + if ($multiple == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Datastore '%s' %s", $dsName, $msg)); + } + next; + } + + my $total_size = 0; + my $lwarn = ''; + my $lcrit = ''; + foreach (@$snapshots) { + if (defined($_->file)) { + foreach my $x (@{$_->file}) { + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $x->fileSize, threshold => [ { label => 'critical_snapshot', exit_litteral => 'critical' }, { label => 'warning_snapshot', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->set_status(exit_litteral => $exit); + my ($size_value, $size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $x->fileSize); + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s: snapshot [%s]=>[%s] [size = %s]", + $exit, $_->folderPath, $x->path, $size_value . ' ' . $size_unit)); + $total_size += $x->fileSize; + } + } + } + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_size, threshold => [ { label => 'critical_total', exit_litteral => 'critical' }, { label => 'warning_total', exit_litteral => 'warning' } ]); + my ($size_value, $size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_size); + $self->{manager}->{output}->set_status(exit_litteral => $exit); + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s: total snapshots [size = %s]", + $exit, $size_value . ' ' . $size_unit)); + + my $extra_label = ''; + $extra_label = '_' . $dsName if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'total_size' . $extra_label, unit => 'B', + value => $total_size, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_total'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_total'), + min => 0); + } + + if (!$self->{manager}->{output}->is_status(compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{manager}->{output}->get_litteral_status(), + short_msg => sprintf("Snapshot sizes exceed limits")); + } +} + +1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshots.pm b/connectors/vmware/src/centreon/esxd/cmddatastoresnapshots.pm deleted file mode 100644 index ac804f17d..000000000 --- a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshots.pm +++ /dev/null @@ -1,224 +0,0 @@ - -package centreon::esxd::cmddatastoresnapshots; - -use strict; -use warnings; -use centreon::esxd::common; - -sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-snapshots'; - - bless $self, $class; - return $self; -} - -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - -sub checkArgs { - my $self = shift; - my ($ds, $filter, $warn, $crit, $warn2, $crit2) = @_; - - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name"); - return 1; - } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; - } - if (defined($warn2) && $warn2 ne "" && $warn2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn2 threshold must be a positive number"); - return 1; - } - if (defined($crit2) && $crit2 ne "" && $crit2 !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit2 threshold must be a positive number"); - return 1; - } - if (defined($warn2) && defined($crit2) && $warn2 ne "" && $crit2 ne "" && $warn2 > $crit2) { - $self->{logger}->writeLogError("ARGS error: warn2 threshold must be lower than crit2 threshold"); - return 1; - } - return 0; -} - -sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) ? $_[2] : ''); - $self->{crit} = (defined($_[3]) ? $_[3] : ''); - $self->{warn2} = (defined($_[4]) ? $_[4] : ''); - $self->{crit2} = (defined($_[5]) ? $_[5] : ''); - $self->{skip_errors} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; -} - -sub run { - my $self = shift; - my %filters = (); - - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{ds}\E$/; - } else { - $filters{name} = qr/$self->{ds}/; - } - - my @properties = ('summary.accessible', 'summary.name', 'browser'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; - } - - my @ds_array = (); - my %ds_names = (); - foreach my $entity_view (@$result) { - next if (!centreon::esxd::common::is_accessible($entity_view->{'summary.accessible'})); - if (defined($entity_view->browser)) { - push @ds_array, $entity_view->browser; - if ($self->{filter} == 1) { - $ds_names{$entity_view->{mo_ref}->{value}} = $entity_view->{'summary.name'}; - } - } - } - - @properties = (); - my $result2; - return if (!($result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties))); - - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ""; - my $output_warning_append = ''; - my $output_critical = ""; - my $output_critical_append = ''; - my $output_warning_total = ""; - my $output_warning_total_append = ''; - my $output_critical_total = ""; - my $output_critical_total_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $output_ok_unit = ''; - my $perfdata = ''; - - foreach my $browse_ds (@$result2) { - my $dsName; - if ($self->{filter} == 1) { - my $tmp_name = $browse_ds->{mo_ref}->{value}; - $tmp_name =~ s/^datastoreBrowser-//i; - $dsName = $ds_names{$tmp_name}; - } else { - $dsName = $self->{ds}; - } - - my ($snapshots, $msg) = centreon::esxd::common::search_in_datastore($self->{obj_esxd}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); - if (!defined($snapshots)) { - $msg =~ s/\n/ /g; - if ($msg =~ /NoPermissionFault/i) { - $msg = "Not enough permissions"; - } - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $dsName . "' $msg"); - } - next; - } - - my $total_size = 0; - my $lwarn = ''; - my $lcrit = ''; - foreach (@$snapshots) { - if (defined($_->file)) { - foreach my $x (@{$_->file}) { - if (defined($self->{crit2}) && $self->{crit2} ne '' && $x->fileSize >= $self->{crit2}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - $lwarn .= " [" . $_->folderPath . ']=>[' . $x->path . "]"; - } elsif (defined($self->{warn2}) && $self->{warn2} ne '' && $x->fileSize >= $self->{warn2}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - $lcrit .= " [" . $_->folderPath . ']=>[' . $x->path . "]"; - } - $total_size += $x->fileSize; - } - } - } - - if ($lcrit ne '') { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$dsName'" . $lcrit); - } - if ($lwarn ne '') { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$dsName'" . $lwarn); - } - - if (defined($self->{crit}) && $self->{crit} && $total_size >= $self->{crit}) { - centreon::esxd::common::output_add(\$output_critical_total, \$output_critical_total_append, ", ", - "'$dsName' Total snapshots used " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} && $total_size >= $self->{warn}) { - centreon::esxd::common::output_add(\$output_warning_total, \$output_warning_total_append, ", ", - "'$dsName' Total snapshots used " . centreon::esxd::common::simplify_number($total_size / 1024 / 1024) . "MB"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } else { - $output_ok_unit .= "'$dsName' Total snapshots size is ok."; - } - - if ($self->{filter} == 1) { - $perfdata .= " 'total_size_" . $dsName . "'=" . $total_size . "o;$self->{warn};$self->{crit};0;"; - } else { - $perfdata .= " 'total_size=" . $total_size . "o;$self->{warn};$self->{crit};0;"; - } - } - - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; - } - if ($output_critical_total ne '' || $output_critical ne '') { - $output .= $output_append . "CRITICAL -"; - if ($output_critical_total ne '') { - $output .= " " . $output_critical_total; - $output_append = ' -'; - } - if ($output_critical ne '') { - $output .= $output_append . " Snapshots size exceed limit: " . $output_critical; - } - $output_append = '. '; - } - if ($output_warning_total ne '' || $output_warning ne '') { - $output .= $output_append . "WARNING -"; - if ($output_warning_total ne '') { - $output .= " " . $output_warning_total; - $output_append = ' -'; - } - if ($output_warning ne '') { - $output .= $output_append . " Snapshots size exceed limit: " . $output_warning; - } - } - if ($status == 0) { - if ($self->{filter} == 1) { - $output .= $output_append . "All Total snapshots size is ok"; - } else { - $output .= $output_append . $output_ok_unit; - } - } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); -} - -1; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 3076839fc..66e93e8b7 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -35,7 +35,7 @@ my @load_modules = ( 'centreon::esxd::cmddatastoreio', 'centreon::esxd::cmddatastoreiops', 'centreon::esxd::cmddatastorehost', - 'centreon::esxd::cmddatastoresnapshots', + 'centreon::esxd::cmddatastoresnapshot', 'centreon::esxd::cmddatastorevm', 'centreon::esxd::cmddatastoreusage', 'centreon::esxd::cmdgetmap', From 291e2b878f1460f434ae1e7504bd473fe6ada673 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Oct 2014 10:56:45 +0100 Subject: [PATCH 104/447] Refs #7246 --- connectors/vmware/centreon_esx_client.pl | 746 ----------------------- 1 file changed, 746 deletions(-) delete mode 100644 connectors/vmware/centreon_esx_client.pl diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl deleted file mode 100644 index 72b66a3c0..000000000 --- a/connectors/vmware/centreon_esx_client.pl +++ /dev/null @@ -1,746 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -no strict "refs"; -use IO::Socket; -use Getopt::Long; - -my $PROGNAME = $0; -my $VERSION = "1.5.6"; -my %ERRORS = (OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, DEPENDENT => 4); -my $socket; -my $separatorin = '~'; - -sub print_help(); -sub print_usage(); -sub print_revision($$); - -my %OPTION = ( - help => undef, version => undef, - "esxd-host" => undef, "esxd-port" => 5700, - vsphere => '', - usage => undef, - "light-perfdata" => undef, - "esx-host" => undef, - datastore => undef, - nic => undef, - warning => undef, - critical => undef, - on => undef, - units => undef, - free => undef, - skip_errors => undef, - skip_not_running => undef, - filter => undef, - - consolidation => undef, - check_disk_limit => undef, - details_value => undef, - - storage_status => undef, - - # For Autodisco - xml => undef, - show_attributes => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions( - "h|help" => \$OPTION{help}, - "V|version" => \$OPTION{version}, - "H|centreon-esxd-host=s" => \$OPTION{'esxd-host'}, - "P|centreon-esxd-port=i" => \$OPTION{'esxd-port'}, - - "vsphere=s" => \$OPTION{vsphere}, - - "u|usage=s" => \$OPTION{usage}, - "e|esx-host=s" => \$OPTION{'esx-host'}, - "vm=s" => \$OPTION{vm}, - - "skip-errors" => \$OPTION{skip_errors}, - "skip-not-running" => \$OPTION{skip_not_running}, - - "filter" => \$OPTION{filter}, - "free" => \$OPTION{free}, - "units=s" => \$OPTION{units}, - "light-perfdata" => \$OPTION{'light-perfdata'}, - "datastore=s" => \$OPTION{datastore}, - - "nic=s" => \$OPTION{nic}, - - "warn" => \$OPTION{warn}, - "crit" => \$OPTION{crit}, - - "on" => \$OPTION{on}, - "check-consolidation" => \$OPTION{consolidation}, - "check-disk" => \$OPTION{check_disk_limit}, - - "w|warning:s" => \$OPTION{warning}, - "c|critical:s" => \$OPTION{critical}, - - "warning2:s" => \$OPTION{warning2}, - "critical2:s" => \$OPTION{critical2}, - - "details-value:s" => \$OPTION{details_value}, - - "storage-status" => \$OPTION{storage_status}, - - "xml" => \$OPTION{xml}, - "show-attributes" => \$OPTION{show_attributes}, -); - -if (defined($OPTION{version})) { - print_revision($PROGNAME, $VERSION); - exit $ERRORS{OK}; -} - -if (defined($OPTION{help})) { - print_help(); - exit $ERRORS{OK}; -} - -############# -# Functions # -############# - -sub print_usage () { - print "Usage: "; - print $PROGNAME."\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; - print " -H centreon-esxd Host (required)\n"; - print " -P centreon-esxd Port (default 5700)\n"; - print " --vsphere vsphere name (default: none)\n"; - print " -u (--usage) What to check. The list and args (required)\n"; - print "\n"; - print "'datastore-snapshots':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; - print " -c (--critical) Critical Threshold in bytes for all snapshots (default none)\n"; - print " --warning2 Warning Threshold in bytes for one snapshot (default none)\n"; - print " --critical2 Critical Threshold in bytes for one snapshot (default none)\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print " --skip-errors Status OK if not enough permissions or others errors (when you checks multiples)\n"; - print "\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2005-2013 Centreon #\n"; - print "# Bugs to http://redmine.merethis.net/ #\n"; - print "##############################################\n"; - print "\n"; - print_usage(); - print "\n"; -} - -sub print_revision($$) { - my $commandName = shift; - my $pluginRevision = shift; - print "$commandName v$pluginRevision (centreon-esxd)\n"; -} - -sub myconnect { - if (!($socket = IO::Socket::INET->new( Proto => "tcp", - PeerAddr => $OPTION{'esxd-host'}, - PeerPort => $OPTION{'esxd-port'}))) { - print "Cannot connect to on '$OPTION{'esxd-host'}': $!\n"; - exit $ERRORS{UNKNOWN}; - } - $socket->autoflush(1); -} - -################# -# Func Usage -################# - -sub maintenancehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub maintenancehost_get_str { - return join($separatorin, - ('maintenancehost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub statushost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub statushost_get_str { - return join($separatorin, - ('statushost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub healthhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{storage_status} = (defined($OPTION{storage_status}) ? 1 : 0); - return 0; -} - -sub healthhost_get_str { - return join($separatorin, - ('healthhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{storage_status})); -} - -sub datastoreusage_check_arg { - if (!defined($OPTION{datastore})) { - print "Option --datastore is required.\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{free} = (defined($OPTION{free}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - if (!defined($OPTION{warning})) { - $OPTION{warning} = ($OPTION{free} == 1) ? 20 : 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ($OPTION{free} == 1) ? 10 : 90; - } - if (defined($OPTION{units})) { - if ($OPTION{units} ne '%' && $OPTION{units} ne 'MB') { - print "Option --units accept '%' or 'MB'.\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - } else { - $OPTION{units} = '%'; - } - return 0; -} - -sub datastoreusage_get_str { - return join($separatorin, - ('datastore-usage', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{free}, $OPTION{units}, $OPTION{skip_errors})); -} - -sub datastoreiops_check_arg { - if (!defined($OPTION{datastore})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - if (!defined($OPTION{details_value})) { - $OPTION{details_value} = 50; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - return 0; -} - -sub datastoreiops_get_str { - return join($separatorin, - ('datastore-iops', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{details_value}, $OPTION{skip_errors})); -} - -sub datastoreio_check_arg { - if (!defined($OPTION{datastore})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - return 0; -} - -sub datastoreio_get_str { - return join($separatorin, - ('datastore-io', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{warning}, $OPTION{critical})); -} - -sub datastoresnapshots_check_arg { - if (!defined($OPTION{datastore})) { - print "Option --datastore is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - if (!defined($OPTION{warning2})) { - $OPTION{warning2} = ''; - } - if (!defined($OPTION{critical2})) { - $OPTION{critical2} = ''; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - return 0; -} - -sub datastoresnapshots_get_str { - return join($separatorin, - ('datastore-snapshots', $OPTION{vsphere}, $OPTION{datastore}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2}, $OPTION{skip_errors})); -} - -sub cpuhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - if (!defined($OPTION{'light-perfdata'})) { - $OPTION{'light-perfdata'} = 0; - } - return 0; -} - -sub cpuhost_get_str { - return join($separatorin, - ('cpuhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical}, $OPTION{'light-perfdata'})); -} - -sub datastoreshost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - if (!defined($OPTION{datastore})) { - $OPTION{datastore} = ''; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - return 0; -} - -sub datastoreshost_get_str { - return join($separatorin, - ('datastoreshost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical} , $OPTION{datastore})); -} - -sub memhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - return 0; -} - -sub memhost_get_str { - return join($separatorin, - ('memhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); -} - -sub swaphost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 0.8; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 1; - } - return 0; -} - -sub swaphost_get_str { - return join($separatorin, - ('swaphost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical})); -} - -sub nethost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{nic})) { - print "Option --nic is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - return 0; -} - -sub nethost_get_str { - return join($separatorin, - ('nethost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{nic}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{skip_errors})); -} - -sub countvmhost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - if (!defined($OPTION{warning2})) { - $OPTION{warning2} = ''; - } - if (!defined($OPTION{critical2})) { - $OPTION{critical2} = ''; - } - return 0; -} - -sub countvmhost_get_str { - return join($separatorin, - ('countvmhost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); -} - -sub uptimehost_check_arg { - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - return 0; -} - -sub uptimehost_get_str { - return join($separatorin, - ('uptimehost', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub cpuvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 80; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 90; - } - if (!defined($OPTION{warning2})) { - $OPTION{warning2} = 5; - } - if (!defined($OPTION{critical2})) { - $OPTION{critical2} = 10; - } - return 0; -} - -sub cpuvm_get_str { - return join($separatorin, - ('cpuvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical}, $OPTION{warning2}, $OPTION{critical2})); -} - -sub toolsvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - $OPTION{skip_not_running} = (defined($OPTION{skip_not_running}) ? 1 : 0); - return 0; -} - -sub toolsvm_get_str { - return join($separatorin, - ('toolsvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{skip_errors}, $OPTION{skip_not_running})); -} - -sub snapshotvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{consolidation} = (defined($OPTION{consolidation}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - $OPTION{skip_not_running} = (defined($OPTION{skip_not_running}) ? 1 : 0); - if (!defined($OPTION{warning})) { - $OPTION{warning} = 86400 * 3; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 86400 * 5; - } - return 0; -} - -sub snapshotvm_get_str { - return join($separatorin, - ('snapshotvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warning}, $OPTION{critical}, $OPTION{consolidation}, $OPTION{skip_errors}, $OPTION{skip_not_running})); -} - -sub limitvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - if ((!defined($OPTION{warn}) && !defined($OPTION{crit})) || defined($OPTION{warn})) { - $OPTION{warn} = 1; - } else { - $OPTION{warn} = 0; - } - $OPTION{crit} = (defined($OPTION{crit}) ? 1 : 0); - $OPTION{check_disk_limit} = (defined($OPTION{check_disk_limit}) ? 1 : 0); - return 0; -} - -sub limitvm_get_str { - return join($separatorin, - ('limitvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{warn}, $OPTION{crit}, $OPTION{check_disk_limit}, $OPTION{skip_errors})); -} - -sub datastoresvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - return 0; -} - -sub datastoresvm_get_str { - return join($separatorin, - ('datastoresvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); -} - -sub memvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = ''; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ''; - } - return 0; -} - -sub memvm_get_str { - return join($separatorin, - ('memvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); -} - -sub swapvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - if (!defined($OPTION{warning})) { - $OPTION{warning} = 0.8; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = 1; - } - return 0; -} - -sub swapvm_get_str { - return join($separatorin, - ('swapvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{warning}, $OPTION{critical})); -} - -sub thinprovisioningvm_check_arg { - if (!defined($OPTION{vm})) { - print "Option --vm is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{on} = (defined($OPTION{on}) ? 1 : 0); - $OPTION{warn} = (defined($OPTION{warn}) ? 1 : 0); - $OPTION{crit} = (defined($OPTION{crit}) ? 1 : 0); - $OPTION{filter} = (defined($OPTION{filter}) ? 1 : 0); - $OPTION{skip_errors} = (defined($OPTION{skip_errors}) ? 1 : 0); - return 0; -} - -sub thinprovisioningvm_get_str { - return join($separatorin, - ('thinprovisioningvm', $OPTION{vsphere}, $OPTION{vm}, $OPTION{filter}, $OPTION{on}, $OPTION{warn}, $OPTION{crit}, $OPTION{skip_errors})); -} - -sub listhost_check_arg { - return 0; -} - -sub listhost_get_str { - return join($separatorin, - ('listhost', $OPTION{vsphere})); -} - -sub listdatastore_check_arg { - if (defined($OPTION{show_attributes})) { - print "name\n"; - exit(0); - } - $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); - return 0; -} - -sub listdatastore_get_str { - return join($separatorin, - ('listdatastore', $OPTION{vsphere}, $OPTION{xml})); -} - -sub listnichost_check_arg { - if (defined($OPTION{show_attributes})) { - print "name\n"; - exit(0); - } - - if (!defined($OPTION{'esx-host'})) { - print "Option --esx-host is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; - } - $OPTION{xml} = (defined($OPTION{xml}) ? 1 : 0); - return 0; -} - -sub listnichost_get_str { - return join($separatorin, - ('listnichost', $OPTION{vsphere}, $OPTION{'esx-host'}, $OPTION{xml})); -} - -sub getmap_check_arg { - if (!defined($OPTION{'esx-host'})) { - $OPTION{'esx-host'} = ""; - } - return 0; -} - -sub getmap_get_str { - return join($separatorin, - ('getmap', $OPTION{vsphere}, $OPTION{'esx-host'})); -} - -sub stats_check_arg { - if (!defined($OPTION{warning})) { - $OPTION{warning} = ""; - } - if (!defined($OPTION{critical})) { - $OPTION{critical} = ""; - } - return 0; -} - -sub stats_get_str { - return join($separatorin, - ('stats', $OPTION{warning}, $OPTION{critical})); -} - -################# -################# - -if (!defined($OPTION{'esxd-host'})) { - print "Option -H (--esxd-host) is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; -} - -if (!defined($OPTION{usage})) { - print "Option -u (--usage) is required\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; -} -if ($OPTION{usage} !~ /^(healthhost|datastore-usage|datastore-io|datastore-iops|datastore-snapshots|maintenancehost|statushost|cpuhost|datastoreshost|nethost|memhost|swaphost|countvmhost|uptimehost|cpuvm|toolsvm|snapshotvm|limitvm|datastoresvm|memvm|swapvm|thinprovisioningvm|listhost|listdatastore|listnichost|getmap|stats)$/) { - print "Usage value is unknown\n"; - print_usage(); - exit $ERRORS{UNKNOWN}; -} - -$OPTION{'usage'} =~ s/-//g; -my $func_check_arg = $OPTION{'usage'} . "_check_arg"; -my $func_get_str = $OPTION{'usage'} . "_get_str"; -&$func_check_arg(); -my $str_send = &$func_get_str(); -myconnect(); -print $socket "$str_send\n"; -my $return = <$socket>; -close $socket; - -chomp $return; -$return =~ /^(-?[0-9]*?)\|/; -my $status_return = $1; -$return =~ s/^(-?[0-9]*?)\|//; -print $return . "\n"; - -if ($status_return < 0) { - $status_return = 3; -} -exit $status_return; - -#print $remote "healthhost||srvi-esx-dev-1.merethis.net\n"; -#print $remote "datastores||LUN-VMFS-QGARNIER|80|90\n"; -#print $remote "maintenancehost||srvi-esx-dev-1.merethis.net\n"; -#print $remote "statushost||srvi-esx-dev-1.merethis.net\n"; -#print $remote "cpuhost||srvi-esx-dev-1.merethis.net|60\n"; -#print $remote "nethost||srvi-esx-dev-1.merethis.net|vmnic1|60\n"; -#print $remote "memhost||srvi-esx-dev-1.merethis.net|80\n"; -#print $remote "swaphost||srvi-esx-dev-1.merethis.net|80\n"; From 8c2ed7124f04f4aa198c8d17a2b477cf2e2383b1 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Oct 2014 11:30:30 +0100 Subject: [PATCH 105/447] + better management + Fix openssl infos --- .../vmware/doc/en/exploitation/index.rst | 2 +- .../vmware/doc/fr/exploitation/index.rst | 2 +- connectors/vmware/src/centreon/esxd/common.pm | 26 +++++++++++++++++++ .../vmware/src/centreon/esxd/connector.pm | 16 +----------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/connectors/vmware/doc/en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst index 6db7b05fc..86c75d681 100644 --- a/connectors/vmware/doc/en/exploitation/index.rst +++ b/connectors/vmware/doc/en/exploitation/index.rst @@ -71,7 +71,7 @@ It is possible to get this kind of errors in the « logs » of « centreon-es ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... -VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. +VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. The bug comes from OpenSSL. It should be fix in OpenSSL 1.0.1h (CVE-2010-5298). It is necessary to create an incident in case there are too many connections error between the daemon and the VirtualCenter. diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index ca75ea1c9..30cf919e5 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -72,7 +72,7 @@ Il est possible de retrouver des erreurs de ce type dans les « logs » de « ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... -Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. +Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. Le bug provient d'OpenSSL. Il devrait être fix dans la version 1.0.1h (CVE-2010-5298). Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 93fabc79f..f6ccafaf5 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -93,6 +93,32 @@ sub connect_vsphere { return 0; } +sub heartbeat { + my (%options) = @_; + my $stime; + + eval { + $stime = $options{connector}->{session1}->get_service_instance()->CurrentTime(); + $options{connector}->{keeper_session_time} = time(); + }; + if ($@) { + $options{connector}->{logger}->writeLogError("$@"); + # Try a second time + eval { + $stime = $options{connector}->{session1}->get_service_instance()->CurrentTime(); + $options{connector}->{keeper_session_time} = time(); + }; + if ($@) { + $options{connector}->{logger}->writeLogError("$@"); + $options{connector}->{logger}->writeLogError("'" . $options{connector}->{whoaim} . "' Ask a new connection"); + # Ask a new connection + $options{connector}->{last_time_check} = time(); + } + } + + $options{connector}->{logger}->writeLogInfo("'" . $options{connector}->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); +} + sub simplify_number { my ($number, $cnt) = @_; $cnt = 2 if (!defined($cnt)); diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index 5a0b34c24..ca6e78dbf 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -1,4 +1,3 @@ -#!/usr/bin/perl -w package centreon::esxd::connector; @@ -271,20 +270,7 @@ sub run { ### if (defined($connector->{keeper_session_time}) && (time() - $connector->{keeper_session_time}) > ($connector->{config_vsphere_session_heartbeat} * 60)) { - my $stime; - - eval { - $stime = $connector->{session1}->get_service_instance()->CurrentTime(); - $connector->{keeper_session_time} = time(); - }; - if ($@) { - $connector->{logger}->writeLogError("$@"); - $connector->{logger}->writeLogError("'" . $connector->{whoaim} . "' Ask a new connection"); - # Ask a new connection - $connector->{last_time_check} = time(); - } else { - $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); - } + centreon::esxd::common::heartbeat(connector => $connector); } my $data_element; From e88ce52fc2337e0b8ee904aa007c26fd6483d75d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Oct 2014 11:50:35 +0100 Subject: [PATCH 106/447] + Put ipc in directory --- .../vmware/src/centreon/esxd/connector.pm | 4 +-- .../src/centreon/script/centreonesxd.pm | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index ca6e78dbf..ef7ca739d 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -164,7 +164,7 @@ sub reqclient { $self->{modules_registry}->{$result->{command}}->initArgs(arguments => $result); $self->{modules_registry}->{$result->{command}}->run(); - centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc://routing.ipc'); + centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc:///tmp/centreonesxd/routing.ipc'); zmq_close($backend); exit(0); } @@ -198,7 +198,7 @@ sub run { $backend = zmq_socket($context, ZMQ_DEALER); zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); zmq_setsockopt($backend, ZMQ_LINGER, 0); # we discard - zmq_connect($backend, 'ipc://routing.ipc'); + zmq_connect($backend, 'ipc:///tmp/centreonesxd/routing.ipc'); centreon::esxd::common::response(token => 'READY', endpoint => $backend, stdout => ''); # Initialize poll set diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 66e93e8b7..f6eec20f8 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -451,6 +451,24 @@ sub create_vsphere_child { $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{pid} = $child_vpshere_pid; } +sub bind_ipc { + my ($self, %options) = @_; + + if (zmq_bind($options{socket}, 'ipc://' . $options{ipc_file}) == -1) { + $self->{logger}->writeLogError("Cannot bind ipc '$options{ipc_file}': $!"); + # try create dir + $self->{logger}->writeLogError("Maybe dirctory not exist. We try to create it!!!"); + if (!mkdir(dirname($options{ipc_file}))) { + zmq_close($options{socket}); + exit(1); + } + if (zmq_bind($options{socket}, 'ipc://' . $options{ipc_file}) == -1) { + zmq_close($options{socket}); + exit(1); + } + } +} + sub run { $centreonesxd = shift; @@ -462,16 +480,15 @@ sub run { my $context = zmq_init(); $frontend = zmq_socket($context, ZMQ_ROUTER); - - zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard - zmq_bind($frontend, 'tcp://*:5700'); - zmq_bind($frontend, 'ipc://routing.ipc'); - if (!defined($frontend)) { $centreonesxd->{logger}->writeLogError("Can't setup server: $!"); exit(1); } - + + zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard + zmq_bind($frontend, 'tcp://*:5700'); + $centreonesxd->bind_ipc(socket => $frontend, ipc_file => '/tmp/centreonesxd/routing.ipc'); + foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { $centreonesxd->{counter_stats}->{$_} = 0; $centreonesxd->create_vsphere_child(vsphere_name => $_, dynamic => 0); From 57f361c88c3a0817ebb1db81ca961614bbb76628 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 9 Jan 2015 11:47:57 +0100 Subject: [PATCH 107/447] Fix #7461 --- .../vmware/src/centreon/esxd/cmdcpuvm.pm | 16 ++++++++--- .../src/centreon/esxd/cmddatastorevm.pm | 24 +++++++++++------ .../vmware/src/centreon/esxd/cmdlimitvm.pm | 18 ++++++++----- .../vmware/src/centreon/esxd/cmdmemvm.pm | 27 ++++++++++++------- .../vmware/src/centreon/esxd/cmdsnapshotvm.pm | 19 ++++++++----- .../vmware/src/centreon/esxd/cmdswapvm.pm | 22 ++++++++++----- .../centreon/esxd/cmdthinprovisioningvm.pm | 18 ++++++++++--- .../vmware/src/centreon/esxd/cmdtoolsvm.pm | 16 ++++++++--- connectors/vmware/src/centreon/esxd/common.pm | 11 +++++++- 9 files changed, 123 insertions(+), 48 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm index 7ca430306..932330274 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm @@ -88,6 +88,9 @@ sub run { $filters{name} = qr/$self->{vm_hostname}/; } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); @@ -150,16 +153,21 @@ sub run { } $long_msg .= ' on last ' . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . ' min'; + my $prefix_msg = "'$entity_view->{name}'"; + if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && + $entity_view->{'config.annotation'} ne '') { + $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + } - $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' $long_msg"); + $self->{manager}->{output}->output_add(long_msg => "$prefix_msg $long_msg"); my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => "'$entity_view->{name}' $short_msg" + short_msg => "$prefix_msg $short_msg" ); } if ($multiple == 0) { - $self->{manager}->{output}->output_add(short_msg => "'$entity_view->{name}' $long_msg"); + $self->{manager}->{output}->output_add(short_msg => "$prefix_msg $long_msg"); } foreach my $id (sort { my ($cida, $cia) = split /:/, $a; @@ -168,7 +176,7 @@ sub run { $cib = -1 if (!defined($cib) || $cib eq ""); $cia <=> $cib} keys %{$values->{$entity_value}}) { my ($counter_id, $instance) = split /:/, $id; - next if ($self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} != $counter_id); + next if ($self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); if ($instance ne "") { $self->{manager}->{output}->perfdata_add(label => 'cpu_' . $instance . '_MHz' . $extra_label, unit => 'MHz', value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0])), diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm index 04d662496..e69d201b3 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm @@ -94,6 +94,9 @@ sub run { $filters{name} = qr/$self->{vm_hostname}/; } my @properties = ('name', 'datastore', 'runtime.connectionState', 'runtime.powerState'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); @@ -166,6 +169,11 @@ sub run { next if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0 && centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; + my $prefix_msg = "'$entity_view->{name}'"; + if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && + $entity_view->{'config.annotation'} ne '') { + $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + } $finded |= 1; my %datastore_lun = (); @@ -187,20 +195,20 @@ sub run { my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read iops on '%s' is %s", - $entity_view->{name}, $_, $read_counter)); + $self->{manager}->{output}->output_add(long_msg => sprintf("%s read iops on '%s' is %s", + $prefix_msg, $_, $read_counter)); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' read iops on '%s' is %s", - $entity_view->{name}, $_, $read_counter)); + short_msg => sprintf("%s read iops on '%s' is %s", + $prefix_msg, $_, $read_counter)); } $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write iops on '%s' is %s", - $entity_view->{name}, $_, $write_counter)); + $self->{manager}->{output}->output_add(long_msg => sprintf("%s write iops on '%s' is %s", + $prefix_msg, $_, $write_counter)); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' write iops on '%s' is %s", - $entity_view->{name}, $_, $write_counter)); + short_msg => sprintf("%s write iops on '%s' is %s", + $prefix_msg, $_, $write_counter)); } my $extra_label = ''; diff --git a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm index 86e8bc93b..dd17f9542 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm @@ -76,7 +76,11 @@ sub display_verbose { $self->{manager}->{output}->output_add(long_msg => $options{label}); foreach my $vm (sort keys %{$options{vms}}) { - $self->{manager}->{output}->output_add(long_msg => ' ' . $vm); + my $prefix = $vm; + if ($options{vms}->{$vm} ne '') { + $prefix .= ' [' . centreon::esxd::common::strip_cr(value => $options{vms}->{$vm}) . ']'; + } + $self->{manager}->{output}->output_add(long_msg => ' ' . $prefix); } } @@ -92,11 +96,13 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } - my @properties; - push @properties, 'name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'; + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); if (defined($self->{check_disk_limit})) { push @properties, 'config.hardware.device'; } + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); @@ -128,12 +134,12 @@ sub run { # CPU Limit if (defined($entity_view->{'config.cpuAllocation.limit'}) && $entity_view->{'config.cpuAllocation.limit'} != -1) { - $cpu_limit{$entity_view->{name}} = 1; + $cpu_limit{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; } # Memory Limit if (defined($entity_view->{'config.memoryAllocation.limit'}) && $entity_view->{'config.memoryAllocation.limit'} != -1) { - $memory_limit{$entity_view->{name}} = 1; + $memory_limit{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; } # Disk @@ -141,7 +147,7 @@ sub run { foreach my $device (@{$entity_view->{'config.hardware.device'}}) { if ($device->isa('VirtualDisk')) { if (defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { - $disk_limit{$entity_view->{name}} = 1; + $disk_limit{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; last; } } diff --git a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm index a377ff775..83a0adbad 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm @@ -90,16 +90,19 @@ sub run { $filters{name} = qr/$self->{vm_hostname}/; } my @properties = ('name', 'summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, - [{'label' => 'mem.active.average', 'instances' => ['']}, - {'label' => 'mem.overhead.average', 'instances' => ['']}, - {'label' => 'mem.vmmemctl.average', 'instances' => ['']}, - {'label' => 'mem.consumed.average', 'instances' => ['']}, - {'label' => 'mem.shared.average', 'instances' => ['']}], + [{label => 'mem.active.average', instancess => ['']}, + {label => 'mem.overhead.average', instances => ['']}, + {label => 'mem.vmmemctl.average', instances => ['']}, + {label => 'mem.consumed.average', instances => ['']}, + {label => 'mem.shared.average', instances => ['']}], $self->{obj_esxd}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); @@ -137,16 +140,22 @@ sub run { my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_consumed); my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $entity_view->{name}, + my $prefix_msg = "'$entity_view->{name}'"; + if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && + $entity_view->{'config.annotation'} ne '') { + $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + } + + $self->{manager}->{output}->output_add(long_msg => sprintf("%s Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $prefix_msg, $total_value . " " . $total_unit, $used_value . " " . $used_unit, $prct_used, $free_value . " " . $free_unit, $prct_free)); if ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $entity_view->{name}, + short_msg => sprintf("%s Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $prefix_msg, $total_value . " " . $total_unit, $used_value . " " . $used_unit, $prct_used, $free_value . " " . $free_unit, $prct_free)); diff --git a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm index bb02c2fbf..3d99af96f 100644 --- a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm @@ -81,11 +81,13 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } - my @properties; - push @properties, 'snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'; + my @properties = ('snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{check_consolidation}) == 1) { push @properties, 'runtime.consolidationNeeded'; } + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); @@ -130,11 +132,16 @@ sub run { my $diff_time = time() - $create_time; my $days = int($diff_time / 60 / 60 / 24); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $prefix_msg = "'$entity_view->{name}'"; + if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && + $entity_view->{'config.annotation'} ne '') { + $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + } if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $vm_errors{$exit}->{$entity_view->{name}} = 1; - $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' snapshot create time: " . $snapshot->createTime); + $self->{manager}->{output}->output_add(long_msg => "$prefix_msg snapshot create time: " . $snapshot->createTime); } } } @@ -157,8 +164,8 @@ sub run { } if (scalar(keys %vm_consolidate) > 0) { $self->{manager}->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf('VMs need consolidation: [%s]', - join('] [', sort keys %vm_consolidate))); + short_msg => sprintf('VMs need consolidation: [%s]', + join('] [', sort keys %vm_consolidate))); } } diff --git a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm index 639a57c27..b7d70d2c9 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm @@ -90,13 +90,17 @@ sub run { $filters{name} = qr/$self->{vm_hostname}/; } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, - [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, - {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], + [{label => 'mem.swapinRate.average', instances => ['']}, + {label => 'mem.swapoutRate.average', instances => ['']}], $self->{obj_esxd}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); @@ -129,15 +133,21 @@ sub run { my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Swap In: %s Swap Out: %s", - $entity_view->{name}, + my $prefix_msg = "'$entity_view->{name}'"; + if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && + $entity_view->{'config.annotation'} ne '') { + $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + } + + $self->{manager}->{output}->output_add(long_msg => sprintf("%s Swap In: %s Swap Out: %s", + $prefix_msg, $swap_in_value . " " . $swap_in_unit . "/s", $swap_out_value . " " . $swap_out_unit . "/s")); if ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Swap In: %s Swap Out: %s", - $entity_view->{name}, + short_msg => sprintf("%s Swap In: %s Swap Out: %s", + $prefix_msg, $swap_in_value . " " . $swap_in_unit . "/s", $swap_out_value . " " . $swap_out_unit . "/s")); } diff --git a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm index aee72d369..25ab9d68c 100644 --- a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm @@ -64,8 +64,12 @@ sub display_verbose { my ($self, %options) = @_; foreach my $vm (sort keys %{$options{vms}}) { - $self->{manager}->{output}->output_add(long_msg => $vm); - foreach my $disk (sort keys %{$options{vms}->{$vm}}) { + my $prefix = $vm; + if ($options{vms}->{$vm}->{description} ne '') { + $prefix .= ' [' . centreon::esxd::common::strip_cr(value => $options{vms}->{$vm}->{description}) . ']'; + } + $self->{manager}->{output}->output_add(long_msg => $prefix); + foreach my $disk (sort keys %{$options{vms}->{$vm}->{disks}}) { $self->{manager}->{output}->output_add(long_msg => ' ' . $disk); } } @@ -84,6 +88,10 @@ sub run { $filters{name} = qr/$self->{vm_hostname}/; } my @properties = ('name', 'config.hardware.device', 'runtime.connectionState', 'runtime.powerState'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); @@ -122,8 +130,10 @@ sub run { if ($_->isa('VirtualDisk')) { if (defined($entry) && $_->backing->thinProvisioned =~ /$maps_match{$entry}->{regexp}/) { $num++; - $disks_vm->{$entity_view->{name}} = {} if (!defined($disks_vm->{$entity_view->{name}})); - $disks_vm->{$entity_view->{name}}->{$_->backing->fileName} = 1; + if (!defined($disks_vm->{$entity_view->{name}})) { + $disks_vm->{$entity_view->{name}} = { disks => {}, description => (defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : '') }; + } + $disks_vm->{$entity_view->{name}}->{disks}->{$_->backing->fileName} = 1; } } } diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm index 8e91fe13c..1202809b8 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm @@ -76,7 +76,11 @@ sub display_verbose { $self->{manager}->{output}->output_add(long_msg => $options{label}); foreach my $vm (sort keys %{$options{vms}}) { - $self->{manager}->{output}->output_add(long_msg => ' ' . $vm); + my $prefix = $vm; + if ($options{vms}->{$vm} ne '') { + $prefix .= ' [' . centreon::esxd::common::strip_cr(value => $options{vms}->{$vm}) . ']'; + } + $self->{manager}->{output}->output_add(long_msg => ' ' . $prefix); } } @@ -93,6 +97,10 @@ sub run { $filters{name} = qr/$self->{vm_hostname}/; } my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); return if (!defined($result)); @@ -122,11 +130,11 @@ sub run { my $tools_status = lc($entity_view->{'summary.guest.toolsStatus'}->val); if ($tools_status eq 'toolsnotinstalled') { - $not_installed{$entity_view->{name}} = 1; + $not_installed{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; } elsif ($tools_status eq 'toolsnotrunning') { - $not_running{$entity_view->{name}} = 1; + $not_running{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; } elsif ($tools_status eq 'toolsold') { - $not_up2date{$entity_view->{name}} = 1; + $not_up2date{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; } } diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index f6ccafaf5..ec3b9e6ac 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -304,7 +304,7 @@ sub generic_performance_values_historic { if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Cannot get value for counters. Maybe you have call a wrong instance'); + short_msg => 'Cannot get value for counters (Maybe, object(s) cannot be reached: disconnected, not running,...)'); return undef; } foreach my $val (@$perfdata) { @@ -502,6 +502,15 @@ sub host_state { return 1; } +sub strip_cr { + my (%options) = @_; + + $options{value} =~ s/^\s+.*\s+$//mg; + $options{value} =~ s/\r//mg; + $options{value} =~ s/\n/ -- /mg; + return $options{value}; +} + sub stats_info { my (%options) = @_; From fd0334cc90e3f49e30d86cb6329de523b5fbde7f Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 9 Jan 2015 12:01:07 +0100 Subject: [PATCH 108/447] + Minor fix protection --- connectors/vmware/src/centreon/esxd/cmdmemvm.pm | 3 ++- connectors/vmware/src/centreon/esxd/common.pm | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm index 83a0adbad..deb9cd552 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm @@ -124,6 +124,7 @@ sub run { multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; my $memory_size = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; + # in KB my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; @@ -135,7 +136,7 @@ sub run { my $prct_used = $mem_consumed * 100 / $memory_size; my $prct_free = 100 - $prct_used; - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_consumed); my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index ec3b9e6ac..abc0a7139 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -127,6 +127,8 @@ sub simplify_number { sub convert_number { my ($number) = shift(@_); + # Avoid error counter empty. But should manage it in code the 'undef'. + $number = 0 if (!defined($number)); $number =~ s/\,/\./; return $number; } From 5971bc54be3396a78f49ca550a3116a6e9d6f556 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 9 Jan 2015 16:36:00 +0100 Subject: [PATCH 109/447] Fix #7789 --- .../src/centreon/esxd/cmdalarmdatacenter.pm | 129 ++++++++++++++++++ .../src/centreon/script/centreonesxd.pm | 1 + 2 files changed, 130 insertions(+) create mode 100644 connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm new file mode 100644 index 000000000..fafbeaa9a --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm @@ -0,0 +1,129 @@ + +package centreon::esxd::cmdalarmdatacenter; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'alarmdatacenter'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{datacenter}) && $options{arguments}->{datacenter} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datacenter cannot be null"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + + if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Need to install Date::Parse CPAN Module"); + return ; + } + + if (defined($self->{datacenter}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datacenter}\E$/; + } elsif (!defined($self->{datacenter})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datacenter}/; + } + + my @properties = ('name', 'triggeredAlarmState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datacenter', \%filters, \@properties); + return if (!defined($result)); + + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("No current alarms on datacenter(s)")); + + my $alarmMgr = centreon::esxd::common::get_view($self->{obj_esxd}, $self->{obj_esxd}->{session1}->get_service_content()->alarmManager, undef); + my $total_alarms = { red => 0, yellow => 0 }; + my $dc_alarms = {}; + foreach my $datacenter_view (@$result) { + $dc_alarms->{$datacenter_view->name} = { red => 0, yellow => 0, alarms => {} }; + next if (!defined($datacenter_view->triggeredAlarmState)); + foreach(@{$datacenter_view->triggeredAlarmState}) { + next if ($_->overallStatus->val !~ /(red|yellow)/i); + if (defined($self->{filter_time}) && $self->{filter_time} ne '') { + my $time_sec = Date::Parse::str2time($_->time); + next if (time() - $time_sec > $self->{filter_time}); + } + my $entity = centreon::esxd::common::get_view($self->{obj_esxd}, $_->entity, ['name']); + my $alarm = centreon::esxd::common::get_view($self->{obj_esxd}, $_->alarm, ['info']); + + $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, + time => $_->time, name => $alarm->info->name, + description => $alarm->info->description, + status => $_->overallStatus->val}; + $dc_alarms->{$datacenter_view->name}->{$_->overallStatus->val}++; + } + } + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{yellow}, + threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{yellow})); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{red}, threshold => [ { label => 'critical', exit_litteral => 'critical' } ]); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{red})); + } + + foreach my $dc_name (keys %{$dc_alarms}) { + $self->{manager}->{output}->output_add(long_msg => sprintf("Checking datacenter %s", $dc_name)); + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", + $dc_alarms->{$dc_name}->{yellow}, $dc_alarms->{$dc_name}->{red})); + foreach my $alert (keys %{$dc_alarms->{$dc_name}->{alarms}}) { + $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s", + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{status}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{name}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{time}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{type}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{description} + )); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index f6eec20f8..9e19fcd94 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -29,6 +29,7 @@ my $VERSION = "1.6.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( + 'centreon::esxd::cmdalarmdatacenter', 'centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', 'centreon::esxd::cmdcpuvm', From 4d8e8cf8f4b6431aae62b41adb6e27b09665bc23 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 9 Jan 2015 16:46:52 +0100 Subject: [PATCH 110/447] Fix #6411 --- connectors/vmware/centreon_esxd-init | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/centreon_esxd-init b/connectors/vmware/centreon_esxd-init index 1f36789de..40739cf69 100644 --- a/connectors/vmware/centreon_esxd-init +++ b/connectors/vmware/centreon_esxd-init @@ -16,6 +16,7 @@ servicename=$(basename "$0") OPTIONS="" user=root timeout=60 +start_timeout=5 pidfile=/var/run/centreon_esxd.pid @@ -52,12 +53,27 @@ start() { else daemon --user $user ''$binary' '$OPTIONS' > /dev/null 2>&1 &' fi - pid=$(pidofproc $binary) - RETVAL=$? - echo $pid > $pidfile + + sleep 2 + + i=0 + while : ; do + if [ "$i" -gt $start_timeout ] ; then + failure $"service not launched" + echo + return 1 + fi + pid=$(pidofproc $binary) + if [ -n "$pid" ] ; then + echo $pid > $pidfile + break + fi + sleep 1 + i=$(($i + 1)) + done success $"service launched" echo - return $RETVAL + return 0 } stop() { From 1b33d4ad59001ccc0fa86dd4d0617433d2f47035 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 9 Jan 2015 16:52:51 +0100 Subject: [PATCH 111/447] Refs #7789 --- connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm index fafbeaa9a..7f752bb7a 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm @@ -39,8 +39,8 @@ sub initArgs { } $self->{manager} = centreon::esxd::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); } sub set_connector { @@ -95,6 +95,7 @@ sub run { description => $alarm->info->description, status => $_->overallStatus->val}; $dc_alarms->{$datacenter_view->name}->{$_->overallStatus->val}++; + $total_alarms->{$_->overallStatus->val}++; } } From ea4183f63f3126c0b37fc0eebe9686ec89772512 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Thu, 22 Jan 2015 10:50:32 +0100 Subject: [PATCH 112/447] Update doc --- .../vmware/doc/en/exploitation/index.rst | 11 +- .../vmware/doc/en/installation/index.rst | 124 +++++++----------- .../vmware/doc/fr/exploitation/index.rst | 13 +- .../vmware/doc/fr/installation/index.rst | 123 +++++++---------- 4 files changed, 110 insertions(+), 161 deletions(-) diff --git a/connectors/vmware/doc/en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst index 86c75d681..46d57c25f 100644 --- a/connectors/vmware/doc/en/exploitation/index.rst +++ b/connectors/vmware/doc/en/exploitation/index.rst @@ -10,7 +10,7 @@ Centreon-esxd is a Perl program in charged to get back VMWare indicators. This p By default "centreon-esxd" starts at least two processes (named "handle-client" and "handle-vsphere-xxxx") : *« handle-client »*: - *Process waiting for requests of "centron-esx-client.pl" clients.* + *Process waiting for requests of clients.* Steps of operation : @@ -38,7 +38,8 @@ The "centreon-esxd" program only works in "daemon" mode (a client is needed). Connector configuration ----------------------- -The « centreon-esxd » daemon is configured with the « centreon_esxd.pm » configuration file :: +The « centreon-esxd » daemon is configured with the « centreon_esxd.pm » configuration file: +:: %centreonesxd_config = ( vsphere_server => { @@ -49,7 +50,8 @@ The « centreon-esxd » daemon is configured with the « centreon_esxd.pm » ); « vsphere_server » attribute configures VirtualCenter access. -In case you have many VirtualCenters, the configuration is (note the use of "," as a separator) :: +In case you have many VirtualCenters, the configuration is (note the use of "," as a separator): +:: %centreonesxd_config = ( vsphere_server => { @@ -67,7 +69,8 @@ In case you have many VirtualCenters, the configuration is (note the use of "," Troubleshooting --------------- -It is possible to get this kind of errors in the « logs » of « centreon-esxd » :: +It is possible to get this kind of errors in the « logs » of « centreon-esxd »: +:: ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 1d6b0be3c..9b0d6dd86 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -8,25 +8,29 @@ Prerequisites Software Recommandations ```````````````````````` -The "centreon-esxd" connector has been tested on red-hat 5 and 6 with rpms. +The "centreon-esxd" connector has been only tested on red-hat 6 with rpms. Installation on other system is possible but is outside the scope of this document (Debian,...). -==================== ===================== -Software Version -==================== ===================== -VMWare SDK Perl 5.1 -Perl 5.8 -centreon-esxd 1.4 -centreon-common-perl 2.5 -==================== ===================== +====================== ===================== +Software Version +====================== ===================== +VMWare SDK Perl 5.1.0-780721 +Perl 5.8 +centreon-esxd 1.6.0 +perl-centreon-base 2.5.0 +centreon-plugins-base 1.10 +ZeroMQ 3.x +Perl ZMQ::LibZMQ3 1.19 +Perl ZMQ::Constants 1.04 +====================== ===================== .. warning:: - The "centreon-esxd" RPMS provided by Merethis is designed to work with Centreon 2.5 (CES 2.2 or CES 3), it does not work with Centreon 2.4. + The "centreon-esxd" RPMS provided by Merethis is designed to work with Centreon 2.5 (CES 3), it does not work with Centreon 2.4. Hardware Recommandations ```````````````````````` -Hardware prerequisites will depend of check numbers. Minimal used ressources are : +Hardware prerequisites will depend of check numbers. Minimal used resources are : * RAM : 512 Mo (May slightly increase with the number of checks). * CPU : same as poller server. @@ -34,61 +38,7 @@ Hardware prerequisites will depend of check numbers. Minimal used ressources are Centreon-esxd Installation - centos/rhel 5 systems ================================================== -SDK Perl VMWare Installation -```````````````````````````` - -The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommandation (only tested with version below). - -======================= ===================== ====================== -Dependency Version Repository -======================= ===================== ====================== -perl-libwww-perl 5.805 redhat/centos base -perl-XML-LibXML 1.58 redhat/centos base -perl-Class-MethodMaker 2.18 ces base -perl-Crypt-SSLeay 0.51 redhat/centos base -perl-SOAP-Lite 0.712 ces base -perl-UUID 0.04 ces base -perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs -======================= ===================== ====================== - -Install following dependency:: - - root # yum install perl-VMware-vSphere - -Requirements -``````````````````````````````` - -« perl-centreon-base » is a prerequisite for « centreon_esxd ». (Module in Centreon 2.5) - -centreon-esxd Installation with rpm -``````````````````````````````````` - -Install the connector:: - - root # yum install ces-plugins-Virtualization-VMWare - -centreon-esxd Installation with source -`````````````````````````````````````` - -Download « centreon-esxd » archive, then install :: - - root # tar zxvf centreon-esxd-1.5.4.tar.gz - root # cd centreon-esxd-1.5.4 - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/ - root # cp lib/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/esxd/ - root # cp centreonesxd.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ - -Configure "centreon-esxd" daemon to start at boot :: - - root # chkconfig --level 2345 centreon_esxd on - -*"centreon_esx_client.pl" is the corresponding nagios plugin.* +Not tested on centos/rhel 5. There is a problem with Perl ZMQ::LibZMQ3 module. Centreon-esxd Installation - centos/rhel 6 systems ================================================== @@ -110,29 +60,41 @@ perl-UUID 0.04 centreon plugin-packs perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs ======================= ===================== ====================== -Install following dependency:: +Install following dependency: +:: root # yum install perl-VMware-vSphere Requirements ``````````````````````````````` -« perl-centreon-base » is a prerequisite for « centreon_esxd ». (Module in Centreon 2.5) +Following prerequisites are mandatory for « centreon_esxd »: + +* « perl-centreon-base »: module since Centreon 2.5 (repository ces standard) +* « centreon-plugins-base »: in repository centreon plugin-packs +* « zeromq » and Perl binding: in repository ces standard or EPEL centreon-esxd Installation with rpm ``````````````````````````````````` -Install the connector:: +Install the connector: +:: root # yum install ces-plugins-Virtualization-VMWare +Install the client: +:: + + root # yum install ces-plugins-Virtualization-VMWare-client + centreon-esxd Installation with source `````````````````````````````````````` -Download « centreon-esxd » archive, then install :: +Download « centreon-esxd » archive, then install: +:: - root # tar zxvf centreon-esxd-1.5.4.tar.gz - root # cd centreon-esxd-1.5.4 + root # tar zxvf centreon-esxd-1.6.0.tar.gz + root # cd centreon-esxd-1.6.0 root # cp centreon_esxd /usr/bin/ root # mkdir -p /etc/centreon @@ -140,11 +102,21 @@ Download « centreon-esxd » archive, then install :: root # cp centreon_esxd-init /etc/init.d/centreon_esxd root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp lib/* /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + root # cp centreon/esxd/* /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp centreon/script/centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ -Configure "centreon-esxd" daemon to start at boot :: +Configure "centreon-esxd" daemon to start at boot: +:: root # chkconfig --level 2345 centreon_esxd on -*"centreon_esx_client.pl" is the corresponding nagios plugin.* +Install the client: +:: + + root # git clone http://git.centreon.com/centreon-plugins.git + root # cd centreon-plugins + root # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + root # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + root # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + root # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + root # cp centreon_plugins.pl /usr/lib/nagios/plugins/ diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index 30cf919e5..fe63091c1 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -10,7 +10,7 @@ Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWar Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : *« handle-client »*: - *Processus en attente des demandes des clients « centreon_esx_client.pl ».* + *Processus en attente des demandes clientes.* Voici le fonctionnement : @@ -39,8 +39,9 @@ Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». Configuration du connecteur --------------------------- -Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante :: - +Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante : +:: + %centreonesxd_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', @@ -50,7 +51,8 @@ Le daemon « centreon-esxd » possède un fichier de configuration « centreo ); L'attribut « vsphere_server » permet de configurer les accès aux différents VirtualCenter. -Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter la "," de séparation) :: +Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter la "," de séparation) : +:: %centreonesxd_config = ( vsphere_server => { @@ -68,7 +70,8 @@ Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter Troubleshooting --------------- -Il est possible de retrouver des erreurs de ce type dans les « logs » de « centreon-esxd » :: +Il est possible de retrouver des erreurs de ce type dans les « logs » de « centreon-esxd » : +:: ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index 145f3e97f..c5028a55c 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -8,20 +8,24 @@ Pré-Requis Préconisations logicielles `````````````````````````` -Le connecteur "centreon-esxd" est testé et validé sur red-hat 5 et 6 avec des rpms. +Le connecteur "centreon-esxd" est testé et validé sur red-hat 6 uniquement avec des rpms. L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Debian, ...). -==================== ===================== -Logiciels Version -==================== ===================== +====================== ===================== +Logiciels Version +====================== ===================== VMWare SDK Perl 5.1.0-780721 Perl 5.8 -centreon-esxd 1.5.4 +centreon-esxd 1.6.0 perl-centreon-base 2.5.0 -==================== ===================== +centreon-plugins-base 1.10 +ZeroMQ 3.x +Perl ZMQ::LibZMQ3 1.19 +Perl ZMQ::Constants 1.04 +====================== ===================== .. warning:: - Le connecteur "centreon-esxd" fourni par Merethis est conçu pour fonctionner Centreon 2.5 (CES 2.2 ou CES 3), il ne fonctionne pas avec Centreon 2.4. + Le connecteur "centreon-esxd" fourni par Merethis est conçu pour fonctionner Centreon 2.5 (CES 3), il ne fonctionne pas avec Centreon 2.4. Préconisations matérielles `````````````````````````` @@ -34,63 +38,7 @@ Le matériel nécessaire dépend du nombre de demandes de vérifications. Par d Installation de centreon-esxd - Environnement centos/rhel 5 =========================================================== -Installation du SDK Perl VMWare -``````````````````````````````` - -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). - -======================= ===================== ====================== -Dépendance Version Dépôt -======================= ===================== ====================== -perl-libwww-perl 5.805 redhat/centos base -perl-XML-LibXML 1.58 redhat/centos base -perl-Class-MethodMaker 2.18 ces base -perl-Crypt-SSLeay 0.51 redhat/centos base -perl-SOAP-Lite 0.712 ces base -perl-UUID 0.04 ces base -perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs -======================= ===================== ====================== - -Installer la dépendance suivante:: - - root # yum install perl-VMware-vSphere - -Pré-requis -``````````````````````````````````````` - -« perl-centreon-base » est nécessaire pour le fonctionnement de « centreon_esxd ». Ce module est présent à partir de Centreon 2.5. - -Installation de centreon-esxd par rpm -````````````````````````````````````` - -Installer le connecteur:: - - root # yum install ces-plugins-Virtualization-VMWare - -Installation de centreon-esxd par les sources -````````````````````````````````````````````` - -Télécharger l'archive de « centreon-esxd ». - -Installer les fichiers:: - - root # tar zxvf centreon-esxd-1.5.4.tar.gz - root # cd centreon-esxd-1.5.4 - root # cp centreon_esxd /usr/bin/ - - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd - - root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp lib/* /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ - -Activer le daemon « centreon-esxd » au démarrage:: - - root # chkconfig --level 2345 centreon_esxd on - -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* +Le connecteur n'a pas été testé et validé en centos/rhel 5. Installation de centreon-esxd - Environnement centos/rhel 6 =========================================================== @@ -112,31 +60,43 @@ perl-UUID 0.04 centreon plugin-packs perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs ======================= ===================== ====================== -Installer la dépendance suivante:: +Installer la dépendance suivante: +:: root # yum install perl-VMware-vSphere Pré-requis ``````````````````````````````````````` -« perl-centreon-base » est nécessaire pour le fonctionnement de « centreon_esxd ». Ce module est présent à partir de Centreon 2.5. +Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_esxd »: + +* « perl-centreon-base » : module est présent à partir de Centreon 2.5 (dépôt ces standard) +* « centreon-plugins-base » : présent dans le dépôt centreon plugin-packs +* « zeromq » et le binding Perl : présent dans le dépôt ces standard ou EPEL Installation de centreon-esxd par rpm ````````````````````````````````````` -Installer le connecteur:: +Installer le connecteur: +:: root # yum install ces-plugins-Virtualization-VMWare +Installer le client: +:: + + root # yum install ces-plugins-Virtualization-VMWare-client + Installation de centreon-esxd par les sources ````````````````````````````````````````````` Télécharger l'archive de « centreon-esxd ». -Installer les fichiers:: - - root # tar zxvf centreon-esxd-1.5.4.tar.gz - root # cd centreon-esxd-1.5.4 +Installer les fichiers: +:: + + root # tar zxvf centreon-esxd-1.6.0.tar.gz + root # cd centreon-esxd-1.6.0 root # cp centreon_esxd /usr/bin/ root # mkdir -p /etc/centreon @@ -144,13 +104,24 @@ Installer les fichiers:: root # cp centreon_esxd-init /etc/init.d/centreon_esxd root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp lib/* /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + root # cp centreon/esxd/* /usr/share/perl5/vendor_perl/centreon/esxd/ + root # cp centreon/script/centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + +Activer le daemon « centreon-esxd » au démarrage: +:: -Activer le daemon « centreon-esxd » au démarrage:: - root # chkconfig --level 2345 centreon_esxd on -*Le plugin « nagios » correspond au fichier « centreon_esx_client.pl ».* +Installer le client: +:: + + root # git clone http://git.centreon.com/centreon-plugins.git + root # cd centreon-plugins + root # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + root # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + root # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + root # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + root # cp centreon_plugins.pl /usr/lib/nagios/plugins/ + From adb2362b725940e7a9feb44ccf96a43244b19fdd Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 26 Jan 2015 14:30:26 +0100 Subject: [PATCH 113/447] + Fix error undefined message for centos 5 --- connectors/vmware/src/centreon/esxd/common.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index abc0a7139..33b118cdc 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -26,7 +26,7 @@ sub init_response { sub response { my (%options) = @_; - my $stdout; + my $stdout = ''; if (!defined($options{stdout})) { local *STDOUT; $manager_display->{output}->{option_results}->{output_json} = 1; From 895f24100c8472f388810d1b36eb4d65ef4e2694 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 26 Jan 2015 16:28:19 +0100 Subject: [PATCH 114/447] + Add perfdata for tools-vm mode --- .../vmware/src/centreon/esxd/cmdcountvmhost.pm | 12 +++++++----- connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm | 13 +++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm index 7601a0987..a8fe63c2f 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm @@ -139,11 +139,13 @@ sub run { $labels->[0])); } - $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, - value => $vm_states{$labels->[0]}, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), - min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); + if ($multiple == 1) { + $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, + value => $vm_states{$labels->[0]}, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), + min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); + } } } } diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm index 1202809b8..ef7768591 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm @@ -156,6 +156,19 @@ sub run { short_msg => sprintf('%d VM with VMTools not installed', scalar(keys %not_installed))); $self->display_verbose(label => 'vmtools not installed:', vms => \%not_installed); } + + if ($multiple == 1) { + my $total = scalar(keys %not_up2date) + scalar(keys %not_running) + scalar(keys %not_installed); + $self->{manager}->{output}->perfdata_add(label => 'not_updated', + value => scalar(keys %not_up2date), + min => 0, max => $total); + $self->{manager}->{output}->perfdata_add(label => 'not_running', + value => scalar(keys %not_running), + min => 0, max => $total); + $self->{manager}->{output}->perfdata_add(label => 'not_installed', + value => scalar(keys %not_installed), + min => 0, max => $total); + } } 1; From 26397999842c07545fbbdc09a0f3026b7a9b426a Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 27 Jan 2015 15:42:02 +0100 Subject: [PATCH 115/447] Fix empty for NasDatastores and type in list --- connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm | 8 ++++++++ connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm index cae46986a..b6517f582 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm @@ -96,6 +96,7 @@ sub run { #my %uuid_list = (); my %disk_name = (); my %datastore_lun = (); + my $ds_checked = 0; foreach (@$result) { next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, name => $_->{'summary.name'}, @@ -106,6 +107,7 @@ sub run { if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; # Not need. We are on Datastore level (not LUN level) + $ds_checked = 1; foreach my $extent (@{$_->info->vmfs->extent}) { $disk_name{$extent->diskName} = $_->info->vmfs->name; if (!defined($datastore_lun{$_->info->vmfs->name})) { @@ -118,6 +120,12 @@ sub run { #} } + if ($ds_checked == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "No Vmfs datastore(s) checked. Cannot get iops from Nas datastore(s)"); + return ; + } + my @vm_array = (); my %added_vm = (); foreach my $entity_view (@$result) { diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm b/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm index 451199aa7..1d94f46ff 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm @@ -72,11 +72,13 @@ sub run { foreach my $datastore (@$result) { if (defined($self->{disco_show})) { $self->{manager}->{output}->add_disco_entry(name => $datastore->summary->name, - accessible => $datastore->summary->accessible); + accessible => $datastore->summary->accessible, + type => $datastore->summary->type); } else { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [%s]", + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [%s] [%s]", $datastore->summary->name, - $datastore->summary->accessible)); + $datastore->summary->accessible, + $datastore->summary->type)); } } From 89ae2f01312f8463663ba83ffa794b626524161d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 2 Feb 2015 14:14:54 +0100 Subject: [PATCH 116/447] + Add a mode for alarms on host (vmware) --- .../src/centreon/esxd/cmdalarmdatacenter.pm | 13 ++ .../vmware/src/centreon/esxd/cmdalarmhost.pm | 143 ++++++++++++++++++ .../vmware/src/centreon/esxd/cmdhealthhost.pm | 5 + .../src/centreon/script/centreonesxd.pm | 1 + 4 files changed, 162 insertions(+) create mode 100644 connectors/vmware/src/centreon/esxd/cmdalarmhost.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm index 7f752bb7a..2dab2186a 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm @@ -53,6 +53,7 @@ sub run { my $self = shift; my %filters = (); + my $multiple = 0; if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', @@ -72,6 +73,9 @@ sub run { my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datacenter', \%filters, \@properties); return if (!defined($result)); + if (scalar(@$result) > 1) { + $multiple = 1; + } $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on datacenter(s)")); @@ -124,6 +128,15 @@ sub run { $dc_alarms->{$dc_name}->{alarms}->{$alert}->{description} )); } + + my $extra_label = ''; + $extra_label = '_' . $dc_name if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'alarm_warning' . $extra_label, + value => $dc_alarms->{$dc_name}->{yellow}, + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'alarm_critical' . $extra_label, + value => $dc_alarms->{$dc_name}->{red}, + min => 0); } } diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm new file mode 100644 index 000000000..9df850472 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm @@ -0,0 +1,143 @@ + +package centreon::esxd::cmdalarmhost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'alarmhost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + + if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Need to install Date::Parse CPAN Module"); + return ; + } + + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + + my @properties = ('name', 'triggeredAlarmState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("No current alarms on host(s)")); + + my $alarmMgr = centreon::esxd::common::get_view($self->{obj_esxd}, $self->{obj_esxd}->{session1}->get_service_content()->alarmManager, undef); + my $total_alarms = { red => 0, yellow => 0 }; + my $dc_alarms = {}; + foreach my $datacenter_view (@$result) { + $dc_alarms->{$datacenter_view->name} = { red => 0, yellow => 0, alarms => {} }; + next if (!defined($datacenter_view->triggeredAlarmState)); + foreach(@{$datacenter_view->triggeredAlarmState}) { + next if ($_->overallStatus->val !~ /(red|yellow)/i); + if (defined($self->{filter_time}) && $self->{filter_time} ne '') { + my $time_sec = Date::Parse::str2time($_->time); + next if (time() - $time_sec > $self->{filter_time}); + } + my $entity = centreon::esxd::common::get_view($self->{obj_esxd}, $_->entity, ['name']); + my $alarm = centreon::esxd::common::get_view($self->{obj_esxd}, $_->alarm, ['info']); + + $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, + time => $_->time, name => $alarm->info->name, + description => $alarm->info->description, + status => $_->overallStatus->val}; + $dc_alarms->{$datacenter_view->name}->{$_->overallStatus->val}++; + $total_alarms->{$_->overallStatus->val}++; + } + } + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{yellow}, + threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{yellow})); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{red}, threshold => [ { label => 'critical', exit_litteral => 'critical' } ]); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{red})); + } + + foreach my $dc_name (keys %{$dc_alarms}) { + $self->{manager}->{output}->output_add(long_msg => sprintf("Checking host %s", $dc_name)); + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", + $dc_alarms->{$dc_name}->{yellow}, $dc_alarms->{$dc_name}->{red})); + foreach my $alert (keys %{$dc_alarms->{$dc_name}->{alarms}}) { + $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s", + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{status}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{name}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{time}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{type}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{description} + )); + } + + my $extra_label = ''; + $extra_label = '_' . $dc_name if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'alarm_warning' . $extra_label, + value => $dc_alarms->{$dc_name}->{yellow}, + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'alarm_critical' . $extra_label, + value => $dc_alarms->{$dc_name}->{red}, + min => 0); + } +} + +1; diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm index 8d4d8344d..f0c0b1742 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm @@ -175,6 +175,11 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("'%s' %s health checks are green", $entity_view->{name}, $OKCount)); } + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'problems' . $extra_label, + value => $CAlertCount + $WAlertCount, + min => 0, max => $OKCount + $CAlertCount + $WAlertCount); } } diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 9e19fcd94..965bfbc3d 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -30,6 +30,7 @@ my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( 'centreon::esxd::cmdalarmdatacenter', + 'centreon::esxd::cmdalarmhost', 'centreon::esxd::cmdcountvmhost', 'centreon::esxd::cmdcpuhost', 'centreon::esxd::cmdcpuvm', From 992011a060472abc209ae5738d485614cc183c6b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Mon, 2 Feb 2015 15:24:36 +0100 Subject: [PATCH 117/447] + Add mhz usage for cpu-host --- connectors/vmware/src/centreon/esxd/cmdcpuhost.pm | 9 +++++++-- connectors/vmware/src/centreon/esxd/cmdcpuvm.pm | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm index e4ea4202e..83c0aefdf 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm @@ -84,7 +84,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } - my @properties = ('name', 'runtime.connectionState'); + my @properties = ('name', 'runtime.connectionState', 'summary.hardware.numCpuCores', 'summary.hardware.cpuMhz'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); return if (!defined($result)); @@ -94,7 +94,8 @@ sub run { my @instances = ('*'); my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, - [{'label' => 'cpu.usage.average', 'instances' => \@instances}], + [{'label' => 'cpu.usage.average', 'instances' => \@instances}, + {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], $self->{obj_esxd}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); @@ -111,6 +112,7 @@ sub run { multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); @@ -131,6 +133,9 @@ sub run { warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0, max => 100); + $self->{manager}->{output}->perfdata_add(label => 'cpu_total_MHz' . $extra_label, unit => 'MHz', + value => $total_cpu_mhz_average, + min => 0, max => $entity_view->{'summary.hardware.numCpuCores'} * $entity_view->{'summary.hardware.cpuMhz'}); foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm index 932330274..feb912d3d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm @@ -148,7 +148,7 @@ sub run { $self->{manager}->{output}->perfdata_add(label => $entry->{perf_label} . $extra_label, unit => $entry->{perf_unit}, value => $entry->{value}, warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_' . $entry->{label}), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_in' . $entry->{label}), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_' . $entry->{label}), min => $entry->{perf_min}, max => $entry->{perf_max}); } From 528c4e8562291ccc7ef201121ff728e33b3cc6f4 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 10 Feb 2015 16:57:19 +0100 Subject: [PATCH 118/447] Fix countvm perfdata --- .../vmware/src/centreon/esxd/cmdcountvmhost.pm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm index a8fe63c2f..e94aaef32 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm @@ -139,13 +139,11 @@ sub run { $labels->[0])); } - if ($multiple == 1) { - $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, - value => $vm_states{$labels->[0]}, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), - min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); - } + $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, + value => $vm_states{$labels->[0]}, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), + min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); } } } From c8e99a53f89b4c4242ac2e9cb47c514ecc118bad Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 18 Feb 2015 10:11:20 +0100 Subject: [PATCH 119/447] Fix vm not running problem --- connectors/vmware/src/centreon/esxd/cmdlimitvm.pm | 2 +- connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm | 2 +- connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm | 2 +- connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm index dd17f9542..cec7fc709 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm @@ -130,7 +130,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); # CPU Limit if (defined($entity_view->{'config.cpuAllocation.limit'}) && $entity_view->{'config.cpuAllocation.limit'} != -1) { diff --git a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm index 3d99af96f..e207c2e05 100644 --- a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm @@ -113,7 +113,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); if (defined($self->{check_consolidation}) && defined($entity_view->{'runtime.consolidationNeeded'}) && $entity_view->{'runtime.consolidationNeeded'} =~ /^true|1$/i) { $vm_consolidate{$entity_view->{name}} = 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm index 25ab9d68c..fabc604fe 100644 --- a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm @@ -124,7 +124,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); foreach (@{$entity_view->{'config.hardware.device'}}) { if ($_->isa('VirtualDisk')) { diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm index ef7768591..c6251f378 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm @@ -126,7 +126,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - !centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); my $tools_status = lc($entity_view->{'summary.guest.toolsStatus'}->val); if ($tools_status eq 'toolsnotinstalled') { From d350bc453538e4fa15ea3de97cb28445ccf46413 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 20 Feb 2015 11:42:07 +0100 Subject: [PATCH 120/447] + add memory system for alarms --- .../src/centreon/esxd/cmdalarmdatacenter.pm | 24 +++++++++++++++++-- .../vmware/src/centreon/esxd/cmdalarmhost.pm | 19 +++++++++++++++ connectors/vmware/src/centreon/esxd/common.pm | 8 +++---- .../vmware/src/centreon/esxd/connector.pm | 4 ++++ .../src/centreon/script/centreonesxd.pm | 1 + 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm index 2dab2186a..5726a36fd 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm @@ -4,6 +4,8 @@ package centreon::esxd::cmdalarmdatacenter; use strict; use warnings; use centreon::esxd::common; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); sub new { my $class = shift; @@ -52,6 +54,15 @@ sub set_connector { sub run { my $self = shift; + if (defined($self->{memory})) { + $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); + $self->{statefile_cache}->read(statefile_dir => $self->{obj_esxd}->{retention_dir}, + statefile => "cache_vmware_connector_" . $self->{obj_esxd}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{datacenter}) ? md5_hex($self->{datacenter}) : md5_hex('.*')), + statefile_suffix => '', + no_quit => 1); + return if ($self->{statefile_cache}->error() == 1); + } + my %filters = (); my $multiple = 0; @@ -76,21 +87,26 @@ sub run { if (scalar(@$result) > 1) { $multiple = 1; } + $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("No current alarms on datacenter(s)")); + short_msg => sprintf("No current alarms on datacenter(s)")); my $alarmMgr = centreon::esxd::common::get_view($self->{obj_esxd}, $self->{obj_esxd}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $dc_alarms = {}; + my $new_datas = {}; foreach my $datacenter_view (@$result) { $dc_alarms->{$datacenter_view->name} = { red => 0, yellow => 0, alarms => {} }; next if (!defined($datacenter_view->triggeredAlarmState)); - foreach(@{$datacenter_view->triggeredAlarmState}) { + foreach (@{$datacenter_view->triggeredAlarmState}) { next if ($_->overallStatus->val !~ /(red|yellow)/i); if (defined($self->{filter_time}) && $self->{filter_time} ne '') { my $time_sec = Date::Parse::str2time($_->time); next if (time() - $time_sec > $self->{filter_time}); } + $new_datas->{$_->key} = 1; + next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); + my $entity = centreon::esxd::common::get_view($self->{obj_esxd}, $_->entity, ['name']); my $alarm = centreon::esxd::common::get_view($self->{obj_esxd}, $_->alarm, ['info']); @@ -138,6 +154,10 @@ sub run { value => $dc_alarms->{$dc_name}->{red}, min => 0); } + + if (defined($self->{memory})) { + $self->{statefile_cache}->write(data => $new_datas); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm index 9df850472..c3e4c55aa 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm @@ -4,6 +4,8 @@ package centreon::esxd::cmdalarmhost; use strict; use warnings; use centreon::esxd::common; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); sub new { my $class = shift; @@ -51,6 +53,15 @@ sub set_connector { sub run { my $self = shift; + + if (defined($self->{memory})) { + $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); + $self->{statefile_cache}->read(statefile_dir => $self->{obj_esxd}->{retention_dir}, + statefile => "cache_vmware_connector_" . $self->{obj_esxd}->{whoaim} . "_" . (defined($self->{esx_hostname}) ? md5_hex($self->{esx_hostname}) : md5_hex('.*')), + statefile_suffix => '', + no_quit => 1); + return if ($self->{statefile_cache}->error() == 1); + } my %filters = (); my $multiple = 0; @@ -82,6 +93,7 @@ sub run { my $alarmMgr = centreon::esxd::common::get_view($self->{obj_esxd}, $self->{obj_esxd}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $dc_alarms = {}; + my $new_datas = {}; foreach my $datacenter_view (@$result) { $dc_alarms->{$datacenter_view->name} = { red => 0, yellow => 0, alarms => {} }; next if (!defined($datacenter_view->triggeredAlarmState)); @@ -91,6 +103,9 @@ sub run { my $time_sec = Date::Parse::str2time($_->time); next if (time() - $time_sec > $self->{filter_time}); } + $new_datas->{$_->key} = 1; + next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); + my $entity = centreon::esxd::common::get_view($self->{obj_esxd}, $_->entity, ['name']); my $alarm = centreon::esxd::common::get_view($self->{obj_esxd}, $_->alarm, ['info']); @@ -138,6 +153,10 @@ sub run { value => $dc_alarms->{$dc_name}->{red}, min => 0); } + + if (defined($self->{memory})) { + $self->{statefile_cache}->write(data => $new_datas); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 33b118cdc..eb0c3a6d9 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -444,7 +444,7 @@ sub is_running { sub datastore_state { my (%options) = @_; - my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{datastore_state_error}; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{datastore_state_error}; if ($options{state} !~ /^true|1$/) { my $output = "Datastore '" . $options{name} . "' not accessible. Current connection state: '$options{state}'."; @@ -461,8 +461,8 @@ sub datastore_state { sub vm_state { my (%options) = @_; - my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{host_state_error}; - my $power_status = defined($options{powerstatus}) ? $options{powerstatus} : $options{connector}->{centreonesxd_config}->{vm_state_error}; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{host_state_error}; + my $power_status = defined($options{powerstatus}) ? $options{powerstatus} : $options{connector}->{vm_state_error}; if ($options{state} !~ /^connected$/i) { my $output = "VM '" . $options{hostname} . "' not connected. Current Connection State: '$options{state}'."; @@ -489,7 +489,7 @@ sub vm_state { sub host_state { my (%options) = @_; - my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{host_state_error}; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{host_state_error}; if ($options{state} !~ /^connected$/i) { my $output = "Host '" . $options{hostname} . "' not connected. Current Connection State: '$options{state}'."; diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index ef7ca739d..d5c2a4a86 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -46,6 +46,10 @@ sub new { $connector->{config_vsphere_url} = $options{config}->{vsphere_server}->{$options{name}}->{url}; $connector->{config_vsphere_user} = $options{config}->{vsphere_server}->{$options{name}}->{username}; $connector->{config_vsphere_pass} = $options{config}->{vsphere_server}->{$options{name}}->{password}; + $connector->{retention_dir} = $options{config}->{retention_dir}; + $connector->{datastore_state_error} = $options{config}->{datastore_state_error}; + $connector->{vm_state_error} = $options{config}->{vm_state_error}; + $connector->{host_state_error} = $options{config}->{host_state_error}; return $connector; } diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 965bfbc3d..1e86c2b0e 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -84,6 +84,7 @@ sub new { datastore_state_error => 'UNKNOWN', vm_state_error => 'UNKNOWN', host_state_error => 'UNKNOWN', + retention_dir => '/var/lib/centreon/centplugins', vsphere_server => { #'default' => {'url' => 'https://XXXXXX/sdk', # 'username' => 'XXXXX', From e64ae47b67f65211e2a218b0dab704586f0dca52 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 20 Feb 2015 14:23:13 +0100 Subject: [PATCH 121/447] + Add a mode for vmware connector --- .../centreon/esxd/cmdvmoperationcluster.pm | 171 ++++++++++++++++++ connectors/vmware/src/centreon/esxd/common.pm | 7 + .../src/centreon/script/centreonesxd.pm | 3 +- 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm new file mode 100644 index 000000000..261eb6c2d --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm @@ -0,0 +1,171 @@ + +package centreon::esxd::cmdvmoperationcluster; + +use strict; +use warnings; +use centreon::esxd::common; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'vmoperationcluster'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{cluster}) && $options{arguments}->{cluster} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: cluster cannot be null"); + return 1; + } + foreach my $label (('warning_svmotion', 'critical_svmotion', 'warning_vmotion', 'critical_vmotion', + 'warning_clone', 'critical_clone')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_svmotion', 'critical_svmotion', 'warning_vmotion', 'critical_vmotion', + 'warning_clone', 'critical_clone')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; +} + +sub run { + my $self = shift; + + $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); + $self->{statefile_cache}->read(statefile_dir => $self->{obj_esxd}->{retention_dir}, + statefile => "cache_vmware_connector_" . $self->{obj_esxd}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{cluster}) ? md5_hex($self->{cluster}) : md5_hex('.*')), + statefile_suffix => '', + no_quit => 1); + return if ($self->{statefile_cache}->error() == 1); + + if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); + return ; + } + + my %filters = (); + my $multiple = 0; + if (defined($self->{cluster}) && !defined($self->{cluster})) { + $filters{name} = qr/^\Q$self->{cluster}\E$/; + } elsif (!defined($self->{cluster})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{cluster}/; + } + my @properties = ('name'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'ClusterComputeResource', \%filters, \@properties); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + $result, + [{'label' => 'vmop.numVMotion.latest', 'instances' => ['']}, + {'label' => 'vmop.numSVMotion.latest', 'instances' => ['']}, + {'label' => 'vmop.numClone.latest', 'instances' => ['']}], + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); + return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All virtual machine operations are ok")); + } + + my $new_datas = {}; + my $old_datas = {}; + my $checked = 0; + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + my $name = centreon::esxd::common::substitute_name(value => $entity_view->{name}); + my %values = (); + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + + foreach my $label (('Clone', 'VMotion', 'SVMotion')) { + $new_datas->{$label . '_' . $entity_value} = $values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'vmop.num' . $label . '.latest'}->{key} . ":"}[0]; + $old_datas->{$label . '_' . $entity_value} = $self->{statefile_cache}->get(name => $label . '_' . $entity_value); + + next if (!defined($old_datas->{$label . '_' . $entity_value})); + $checked = 1; + + if ($old_datas->{$label . '_' . $entity_value} > $new_datas->{$label . '_' . $entity_value}) { + $old_datas->{$label . '_' . $entity_value} = 0; + } + + my $diff = $new_datas->{$label . '_' . $entity_value} - $old_datas->{$label . '_' . $entity_value}; + $long_msg .= $long_msg_append . $label . ' ' . $diff; + $long_msg_append = ', '; + + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $diff, threshold => [ { label => 'critical_' . lc($label), exit_litteral => 'critical' }, { label => 'warning_' . lc($label), exit_litteral => 'warning' } ]); + push @exits, $exit2; + if ($multiple == 0 || !$self->{manager}->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $label . ' ' . $diff; + $short_msg_append = ', '; + } + + my $extra_label = ''; + $extra_label = '_' . $name if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => lc($label) . $extra_label, + value => $diff, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_' . lc($label)), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_' . lc($label)), + min => 0); + } + + $self->{manager}->{output}->output_add(long_msg => "Cluster '" . $name . "' vm operations: $long_msg"); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => "Cluster '" . $name . "' vm operations: $short_msg" + ); + } + + if ($multiple == 0) { + $self->{manager}->{output}->output_add(short_msg => "Cluster '" . $name . "' vm operations: $long_msg"); + } + } + + if ($checked == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("Buffer creation")); + } + $self->{statefile_cache}->write(data => $new_datas); +} + +1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index eb0c3a6d9..93d6d82e7 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -504,6 +504,13 @@ sub host_state { return 1; } +sub substitute_name { + my (%options) = @_; + + $options{value} =~ s/%2f/\//g; + return $options{value}; +} + sub strip_cr { my (%options) = @_; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 1e86c2b0e..b67d2bfdb 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -55,7 +55,8 @@ my @load_modules = ( 'centreon::esxd::cmdswapvm', 'centreon::esxd::cmdthinprovisioningvm', 'centreon::esxd::cmdtoolsvm', - 'centreon::esxd::cmduptimehost' + 'centreon::esxd::cmduptimehost', + 'centreon::esxd::cmdvmoperationcluster', ); sub new { From 43dd55a0162467e2919dbcdd20a221b0a34f63a6 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Fri, 20 Feb 2015 14:47:07 +0100 Subject: [PATCH 122/447] + add filter on description vm --- connectors/vmware/src/centreon/esxd/cmdcpuvm.pm | 4 ++++ connectors/vmware/src/centreon/esxd/cmddatastorevm.pm | 4 ++++ connectors/vmware/src/centreon/esxd/cmdlimitvm.pm | 4 ++++ connectors/vmware/src/centreon/esxd/cmdmemvm.pm | 4 ++++ connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm | 4 ++++ connectors/vmware/src/centreon/esxd/cmdswapvm.pm | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm index feb912d3d..a60ada907 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm @@ -87,6 +87,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm index e69d201b3..64cd74c5e 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm @@ -93,6 +93,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'datastore', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; diff --git a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm index cec7fc709..202fbe420 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm @@ -96,6 +96,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); if (defined($self->{check_disk_limit})) { push @properties, 'config.hardware.device'; diff --git a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm index deb9cd552..130580c79 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm @@ -89,6 +89,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; diff --git a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm index e207c2e05..8b4e6f236 100644 --- a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm @@ -81,6 +81,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{check_consolidation}) == 1) { push @properties, 'runtime.consolidationNeeded'; diff --git a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm index b7d70d2c9..defd61b0f 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm @@ -89,6 +89,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; From ce2738953aab502b9275ea32f3cf27483bebd56e Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Apr 2015 11:34:33 +0200 Subject: [PATCH 123/447] + Add list-datacenters mode + Add scoping system --- .../src/centreon/esxd/cmdalarmdatacenter.pm | 16 ++-- .../vmware/src/centreon/esxd/cmdalarmhost.pm | 16 ++-- .../src/centreon/esxd/cmdcountvmhost.pm | 10 +- .../vmware/src/centreon/esxd/cmdcpuhost.pm | 22 ++--- .../vmware/src/centreon/esxd/cmdcpuvm.pm | 24 ++--- .../src/centreon/esxd/cmddatastorehost.pm | 18 ++-- .../src/centreon/esxd/cmddatastoreio.pm | 19 ++-- .../src/centreon/esxd/cmddatastoreiops.pm | 26 ++--- .../src/centreon/esxd/cmddatastoresnapshot.pm | 10 +- .../src/centreon/esxd/cmddatastoreusage.pm | 6 +- .../src/centreon/esxd/cmddatastorevm.pm | 22 ++--- .../vmware/src/centreon/esxd/cmdgetmap.pm | 6 +- .../vmware/src/centreon/esxd/cmdhealthhost.pm | 6 +- .../vmware/src/centreon/esxd/cmdlimitvm.pm | 6 +- .../src/centreon/esxd/cmdlistdatacenters.pm | 95 +++++++++++++++++++ .../src/centreon/esxd/cmdlistdatastores.pm | 4 +- .../src/centreon/esxd/cmdlistnichost.pm | 4 +- .../src/centreon/esxd/cmdmaintenancehost.pm | 6 +- .../vmware/src/centreon/esxd/cmdmemhost.pm | 18 ++-- .../vmware/src/centreon/esxd/cmdmemvm.pm | 24 ++--- .../vmware/src/centreon/esxd/cmdnethost.pm | 18 ++-- .../vmware/src/centreon/esxd/cmdsnapshotvm.pm | 8 +- .../vmware/src/centreon/esxd/cmdstatushost.pm | 6 +- .../vmware/src/centreon/esxd/cmdswaphost.pm | 18 ++-- .../vmware/src/centreon/esxd/cmdswapvm.pm | 18 ++-- .../centreon/esxd/cmdthinprovisioningvm.pm | 6 +- .../vmware/src/centreon/esxd/cmdtoolsvm.pm | 6 +- .../vmware/src/centreon/esxd/cmduptimehost.pm | 8 +- .../centreon/esxd/cmdvmoperationcluster.pm | 18 ++-- connectors/vmware/src/centreon/esxd/common.pm | 91 +++++++++++++++--- .../src/centreon/script/centreonesxd.pm | 1 + 31 files changed, 356 insertions(+), 200 deletions(-) create mode 100644 connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm index 5726a36fd..46cf1e5e5 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm @@ -48,7 +48,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -56,8 +56,8 @@ sub run { if (defined($self->{memory})) { $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); - $self->{statefile_cache}->read(statefile_dir => $self->{obj_esxd}->{retention_dir}, - statefile => "cache_vmware_connector_" . $self->{obj_esxd}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{datacenter}) ? md5_hex($self->{datacenter}) : md5_hex('.*')), + $self->{statefile_cache}->read(statefile_dir => $self->{connector}->{retention_dir}, + statefile => "cache_vmware_connector_" . $self->{connector}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{datacenter}) ? md5_hex($self->{datacenter}) : md5_hex('.*')), statefile_suffix => '', no_quit => 1); return if ($self->{statefile_cache}->error() == 1); @@ -66,7 +66,7 @@ sub run { my %filters = (); my $multiple = 0; - if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { + if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{connector}->{module_date_parse_loaded} == 0) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Need to install Date::Parse CPAN Module"); return ; @@ -81,7 +81,7 @@ sub run { } my @properties = ('name', 'triggeredAlarmState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datacenter', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -91,7 +91,7 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on datacenter(s)")); - my $alarmMgr = centreon::esxd::common::get_view($self->{obj_esxd}, $self->{obj_esxd}->{session1}->get_service_content()->alarmManager, undef); + my $alarmMgr = centreon::esxd::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $dc_alarms = {}; my $new_datas = {}; @@ -107,8 +107,8 @@ sub run { $new_datas->{$_->key} = 1; next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); - my $entity = centreon::esxd::common::get_view($self->{obj_esxd}, $_->entity, ['name']); - my $alarm = centreon::esxd::common::get_view($self->{obj_esxd}, $_->alarm, ['info']); + my $entity = centreon::esxd::common::get_view($self->{connector}, $_->entity, ['name']); + my $alarm = centreon::esxd::common::get_view($self->{connector}, $_->alarm, ['info']); $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, time => $_->time, name => $alarm->info->name, diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm index c3e4c55aa..522991d92 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm @@ -48,7 +48,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -56,8 +56,8 @@ sub run { if (defined($self->{memory})) { $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); - $self->{statefile_cache}->read(statefile_dir => $self->{obj_esxd}->{retention_dir}, - statefile => "cache_vmware_connector_" . $self->{obj_esxd}->{whoaim} . "_" . (defined($self->{esx_hostname}) ? md5_hex($self->{esx_hostname}) : md5_hex('.*')), + $self->{statefile_cache}->read(statefile_dir => $self->{connector}->{retention_dir}, + statefile => "cache_vmware_connector_" . $self->{connector}->{whoaim} . "_" . (defined($self->{esx_hostname}) ? md5_hex($self->{esx_hostname}) : md5_hex('.*')), statefile_suffix => '', no_quit => 1); return if ($self->{statefile_cache}->error() == 1); @@ -66,7 +66,7 @@ sub run { my %filters = (); my $multiple = 0; - if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{obj_esxd}->{module_date_parse_loaded} == 0) { + if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{connector}->{module_date_parse_loaded} == 0) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Need to install Date::Parse CPAN Module"); return ; @@ -81,7 +81,7 @@ sub run { } my @properties = ('name', 'triggeredAlarmState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -90,7 +90,7 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on host(s)")); - my $alarmMgr = centreon::esxd::common::get_view($self->{obj_esxd}, $self->{obj_esxd}->{session1}->get_service_content()->alarmManager, undef); + my $alarmMgr = centreon::esxd::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $dc_alarms = {}; my $new_datas = {}; @@ -106,8 +106,8 @@ sub run { $new_datas->{$_->key} = 1; next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); - my $entity = centreon::esxd::common::get_view($self->{obj_esxd}, $_->entity, ['name']); - my $alarm = centreon::esxd::common::get_view($self->{obj_esxd}, $_->alarm, ['info']); + my $entity = centreon::esxd::common::get_view($self->{connector}, $_->entity, ['name']); + my $alarm = centreon::esxd::common::get_view($self->{connector}, $_->alarm, ['info']); $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, time => $_->time, name => $alarm->info->name, diff --git a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm index e94aaef32..3a79ebfd4 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm @@ -60,7 +60,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -76,14 +76,14 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'vm', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - #return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, + #return if (centreon::esxd::common::host_state($self->{connector}, $self->{lhost}, # $$result[0]->{'runtime.connectionState'}->val) == 0); my @vm_array = (); @@ -93,7 +93,7 @@ sub run { } } @properties = ('runtime.powerState'); - my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + my $result2 = centreon::esxd::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); if ($multiple == 1) { @@ -102,7 +102,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm index 83c0aefdf..c968593ac 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm @@ -62,13 +62,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -85,45 +85,45 @@ sub run { } my @properties = ('name', 'runtime.connectionState', 'summary.hardware.numCpuCores', 'summary.hardware.cpuMhz'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Total Average CPU usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", - $entity_view->{name}, $total_cpu_average, int($self->{obj_esxd}->{perfcounter_speriod} / 60))); + $entity_view->{name}, $total_cpu_average, int($self->{connector}->{perfcounter_speriod} / 60))); if ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, short_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", - $entity_view->{name}, $total_cpu_average, int($self->{obj_esxd}->{perfcounter_speriod} / 60))); + $entity_view->{name}, $total_cpu_average, int($self->{connector}->{perfcounter_speriod} / 60))); } my $extra_label = ''; diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm index a60ada907..753d75367 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm @@ -66,13 +66,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -95,18 +95,18 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, {'label' => 'cpu.ready.summation', 'instances' => \@instances}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -116,7 +116,7 @@ sub run { short_msg => sprintf("All cpu usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -124,9 +124,9 @@ sub run { powerstatus => $self->{nopoweredon_status}, multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); - my $total_cpu_ready = centreon::esxd::common::simplify_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{obj_esxd}->{perfcounter_speriod} * 1000) * 100); + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_ready = centreon::esxd::common::simplify_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{connector}->{perfcounter_speriod} * 1000) * 100); my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits; @@ -156,7 +156,7 @@ sub run { min => $entry->{perf_min}, max => $entry->{perf_max}); } - $long_msg .= ' on last ' . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . ' min'; + $long_msg .= ' on last ' . int($self->{connector}->{perfcounter_speriod} / 60) . ' min'; my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { @@ -180,7 +180,7 @@ sub run { $cib = -1 if (!defined($cib) || $cib eq ""); $cia <=> $cib} keys %{$values->{$entity_value}}) { my ($counter_id, $instance) = split /:/, $id; - next if ($self->{obj_esxd}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); + next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); if ($instance ne "") { $self->{manager}->{output}->perfdata_add(label => 'cpu_' . $instance . '_MHz' . $extra_label, unit => 'MHz', value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0])), diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm b/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm index e9dfe7931..51db52214 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm @@ -66,13 +66,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -88,7 +88,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'config.fileSystemVolume.mountInfo', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -108,7 +108,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -153,12 +153,12 @@ sub run { # Vsphere >= 4.1 # You get counters even if datastore is disconnect... - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, undef, $query_perfs, - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Datastore latencies are ok")); @@ -172,8 +172,8 @@ sub run { next if (defined($checked->{$uuid})); $checked->{$uuid} = 1; - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid}[0])); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid}[0])); + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid}[0])); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid}[0])); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read on '%s' is %s ms", diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm index 71550a0bc..5ea1a4e25 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm @@ -60,13 +60,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -82,17 +82,16 @@ sub run { $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary.name', 'summary.accessible'); - - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -103,7 +102,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'}, status => $self->{disconnect_status}, @@ -111,8 +110,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # in KBps - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm index b6517f582..098f8cbb8 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm @@ -60,13 +60,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -82,7 +82,7 @@ sub run { $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -98,7 +98,7 @@ sub run { my %datastore_lun = (); my $ds_checked = 0; foreach (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, name => $_->{'summary.name'}, state => $_->{'summary.accessible'}, status => $self->{disconnect_status}, @@ -139,7 +139,7 @@ sub run { } @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); - my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + my $result2 = centreon::esxd::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); # Remove disconnected or not running vm @@ -154,14 +154,14 @@ sub run { } # Vsphere >= 4.1 - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result2, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); foreach (keys %$values) { my ($vm_id, $id, $disk_name) = split(/:/); @@ -169,12 +169,12 @@ sub run { # RDM Disk. We skip. Don't know how to manage it right now. next if (!defined($disk_name{$disk_name})); - my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{obj_esxd}->{perfcounter_speriod})); - $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; - if (!defined($datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}})) { - $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} = $tmp_value; + my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{connector}->{perfcounter_speriod})); + $datastore_lun{$disk_name{$disk_name}}{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; + if (!defined($datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}})) { + $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}} = $tmp_value; } else { - $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; + $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; } } diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm index d1c6aad30..57f731b96 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm @@ -60,7 +60,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -76,7 +76,7 @@ sub run { $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary.accessible', 'summary.name', 'browser'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -86,7 +86,7 @@ sub run { my @ds_array = (); my %ds_names = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'}, status => $self->{disconnect_status}, @@ -99,7 +99,7 @@ sub run { @properties = (); my $result2; - return if (!($result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties))); + return if (!($result2 = centreon::esxd::common::get_views($self->{connector}, \@ds_array, \@properties))); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All snapshot sizes are ok")); @@ -110,7 +110,7 @@ sub run { $dsName = $ds_names{$tmp_name}; $self->{manager}->{output}->output_add(long_msg => "Checking datastore '$dsName':"); - my ($snapshots, $msg) = centreon::esxd::common::search_in_datastore($self->{obj_esxd}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); + my ($snapshots, $msg) = centreon::esxd::common::search_in_datastore($self->{connector}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); if (!defined($snapshots)) { $msg =~ s/\n/ /g; if ($msg =~ /NoPermissionFault/i) { diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm index e2e3bf440..1ea5b97f7 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm @@ -64,7 +64,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -81,7 +81,7 @@ sub run { } my @properties = ('summary'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -93,7 +93,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, name => $entity_view->summary->name, state => $entity_view->summary->accessible, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm index 64cd74c5e..959581ad6 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm @@ -72,13 +72,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -101,7 +101,7 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -119,7 +119,7 @@ sub run { my $mapped_datastore = {}; my @ds_array = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -137,7 +137,7 @@ sub run { } @properties = ('info'); - my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@ds_array, \@properties); + my $result2 = centreon::esxd::common::get_views($self->{connector}, \@ds_array, \@properties); return if (!defined($result2)); #my %uuid_list = (); @@ -158,13 +158,13 @@ sub run { # Vsphere >= 4.1 # We don't filter. To filter we'll need to get disk from vms - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Datastore IOPS counters are ok")); @@ -190,13 +190,13 @@ sub run { next if ($disk_name{$disk_name} !~ /$ds_regexp/); $datastore_lun{$disk_name{$disk_name}} = { 'disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0 } if (!defined($datastore_lun{$disk_name{$disk_name}})); - $datastore_lun{$disk_name{$disk_name}}->{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}[0]; + $datastore_lun{$disk_name{$disk_name}}->{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}[0]; } foreach (sort keys %datastore_lun) { $finded |= 2; - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{obj_esxd}->{perfcounter_speriod})); + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{connector}->{perfcounter_speriod})); + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{connector}->{perfcounter_speriod})); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("%s read iops on '%s' is %s", diff --git a/connectors/vmware/src/centreon/esxd/cmdgetmap.pm b/connectors/vmware/src/centreon/esxd/cmdgetmap.pm index 1c06df0b9..c5f761e1a 100644 --- a/connectors/vmware/src/centreon/esxd/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/esxd/cmdgetmap.pm @@ -44,7 +44,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -60,7 +60,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'vm'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); $self->{manager}->{output}->output_add(severity => 'OK', @@ -77,7 +77,7 @@ sub run { } @properties = ('name', 'summary.runtime.powerState'); - my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); + my $result2 = centreon::esxd::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); my %vms = (); diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm index f0c0b1742..2e1eee4ba 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm @@ -52,7 +52,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -71,7 +71,7 @@ sub run { my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -83,7 +83,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm index 202fbe420..82d6e6244 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm @@ -68,7 +68,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub display_verbose { @@ -108,7 +108,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -126,7 +126,7 @@ sub run { my %memory_limit = (); my %disk_limit = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm b/connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm new file mode 100644 index 000000000..43726de1e --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm @@ -0,0 +1,95 @@ + +package centreon::esxd::cmdlistdatacenters; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'listdatacenters'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{datacenter}) && $options{arguments}->{datacenter} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datacenter cannot be null"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{connector} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + + if (defined($self->{datacenter}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datacenter}\E$/; + } elsif (!defined($self->{datacenter})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datacenter}/; + } + my @properties = ('name'); + + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); + return if (!defined($result)); + + if (!defined($self->{disco_show})) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => 'List datacenter(s):'); + } + foreach my $datacenter (@$result) { + if (defined($self->{disco_show})) { + $self->{manager}->{output}->add_disco_entry(name => $datacenter->name); + } else { + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s", + $datacenter->name)); + } + } + + if (defined($self->{disco_show})) { + my $stdout; + { + local *STDOUT; + $self->{manager}->{output}->{option_results}->{output_xml} = 1; + open STDOUT, '>', \$stdout; + $self->{manager}->{output}->display_disco_show(); + delete $self->{manager}->{output}->{option_results}->{output_xml}; + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => $stdout); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm b/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm index 1d94f46ff..5c9c2983d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm @@ -44,7 +44,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -62,7 +62,7 @@ sub run { } my @properties = ('summary'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (!defined($self->{disco_show})) { diff --git a/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm b/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm index 72d413065..78d9fc18d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm @@ -44,7 +44,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -53,7 +53,7 @@ sub run { my %filters = (name => $self->{esx_hostname}); my @properties = ('config.network.pnic', 'config.network.vswitch', 'config.network.proxySwitch'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); # Get Name from vswitch diff --git a/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm index 808b727c4..5aef5eecc 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm @@ -56,7 +56,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -74,7 +74,7 @@ sub run { } my @properties = ('name', 'runtime.inMaintenanceMode', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -86,7 +86,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdmemhost.pm b/connectors/vmware/src/centreon/esxd/cmdmemhost.pm index 95e95db13..f44fc447b 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemhost.pm @@ -62,13 +62,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -84,26 +84,26 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'summary.hardware.memorySize', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All memory usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -112,8 +112,8 @@ sub run { my $memory_size = $entity_view->{'summary.hardware.memorySize'}; # in B # in KB - my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; my $prct_free = 100 - $prct_used; diff --git a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm index 130580c79..f65367b08 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdmemvm.pm @@ -68,13 +68,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -97,19 +97,19 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{label => 'mem.active.average', instancess => ['']}, {label => 'mem.overhead.average', instances => ['']}, {label => 'mem.vmmemctl.average', instances => ['']}, {label => 'mem.consumed.average', instances => ['']}, {label => 'mem.shared.average', instances => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -119,7 +119,7 @@ sub run { short_msg => sprintf("All memory usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -130,11 +130,11 @@ sub run { my $memory_size = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; # in KB - my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_ballooning = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_shared = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_ballooning = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_shared = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])) * 1024; my $mem_free = $memory_size - $mem_consumed; my $prct_used = $mem_consumed * 100 / $memory_size; diff --git a/connectors/vmware/src/centreon/esxd/cmdnethost.pm b/connectors/vmware/src/centreon/esxd/cmdnethost.pm index 53d52e9ae..8612fcb1d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdnethost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdnethost.pm @@ -72,13 +72,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -94,7 +94,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'config.network.pnic', 'runtime.connectionState', 'config.network.vswitch', 'config.network.proxySwitch'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -109,7 +109,7 @@ sub run { my $pnic_def_down = {}; my $query_perfs = []; foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -184,12 +184,12 @@ sub run { # Nothing to retrieve. problem before already. return if (scalar(@$query_perfs) == 0); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, undef, $query_perfs, - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; @@ -204,8 +204,8 @@ sub run { my @exits; foreach (sort keys %{$pnic_def_up->{$entity_value}}) { # KBps - my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_}[0])) * 1024 * 8; - my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_}[0])) * 1024 * 8; my $interface_speed = $pnic_def_up->{$entity_value}->{$_} * 1024 * 1024; my $in_prct = $traffic_in * 100 / $interface_speed; my $out_prct = $traffic_out * 100 / $interface_speed; diff --git a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm index 8b4e6f236..3a6d028fd 100644 --- a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm @@ -60,13 +60,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if ($self->{obj_esxd}->{module_date_parse_loaded} == 0) { + if ($self->{connector}->{module_date_parse_loaded} == 0) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Need to install Date::Parse CPAN Module"); return ; @@ -93,7 +93,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); my %vm_consolidate = (); @@ -109,7 +109,7 @@ sub run { short_msg => sprintf("Snapshot(s) OK")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm index 021b2bff6..0ba24b655 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm @@ -50,7 +50,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { @@ -67,7 +67,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -92,7 +92,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm index 7de9ec34e..1ab65443e 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswaphost.pm @@ -62,13 +62,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -84,26 +84,26 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All swap rate usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -111,8 +111,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm index defd61b0f..14f2a8cd5 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdswapvm.pm @@ -68,13 +68,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -98,16 +98,16 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{label => 'mem.swapinRate.average', instances => ['']}, {label => 'mem.swapoutRate.average', instances => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -118,7 +118,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -128,8 +128,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm index fabc604fe..99bbd96e5 100644 --- a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm @@ -57,7 +57,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub display_verbose { @@ -92,7 +92,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -116,7 +116,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm index c6251f378..47e16be82 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm @@ -68,7 +68,7 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub display_verbose { @@ -101,7 +101,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'VirtualMachine', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -118,7 +118,7 @@ sub run { my %not_running = (); my %not_up2date = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmduptimehost.pm b/connectors/vmware/src/centreon/esxd/cmduptimehost.pm index 0550aec9e..1267eeca0 100644 --- a/connectors/vmware/src/centreon/esxd/cmduptimehost.pm +++ b/connectors/vmware/src/centreon/esxd/cmduptimehost.pm @@ -62,13 +62,13 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; - if ($self->{obj_esxd}->{module_date_parse_loaded} == 0) { + if ($self->{connector}->{module_date_parse_loaded} == 0) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Need to install Date::Parse Perl Module."); return ; @@ -84,7 +84,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'runtime.bootTime', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -96,7 +96,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + next if (centreon::esxd::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm index 261eb6c2d..6810a6131 100644 --- a/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm +++ b/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm @@ -58,20 +58,20 @@ sub initArgs { sub set_connector { my ($self, %options) = @_; - $self->{obj_esxd} = $options{connector}; + $self->{connector} = $options{connector}; } sub run { my $self = shift; $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); - $self->{statefile_cache}->read(statefile_dir => $self->{obj_esxd}->{retention_dir}, - statefile => "cache_vmware_connector_" . $self->{obj_esxd}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{cluster}) ? md5_hex($self->{cluster}) : md5_hex('.*')), + $self->{statefile_cache}->read(statefile_dir => $self->{connector}->{retention_dir}, + statefile => "cache_vmware_connector_" . $self->{connector}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{cluster}) ? md5_hex($self->{cluster}) : md5_hex('.*')), statefile_suffix => '', no_quit => 1); return if ($self->{statefile_cache}->error() == 1); - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { + if (!($self->{connector}->{perfcounter_speriod} > 0)) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Can't retrieve perf counters"); return ; @@ -87,20 +87,20 @@ sub run { $filters{name} = qr/$self->{cluster}/; } my @properties = ('name'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'ClusterComputeResource', \%filters, \@properties); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, + my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'vmop.numVMotion.latest', 'instances' => ['']}, {'label' => 'vmop.numSVMotion.latest', 'instances' => ['']}, {'label' => 'vmop.numClone.latest', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); + return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', @@ -118,7 +118,7 @@ sub run { my @exits; foreach my $label (('Clone', 'VMotion', 'SVMotion')) { - $new_datas->{$label . '_' . $entity_value} = $values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'vmop.num' . $label . '.latest'}->{key} . ":"}[0]; + $new_datas->{$label . '_' . $entity_value} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.num' . $label . '.latest'}->{key} . ":"}[0]; $old_datas->{$label . '_' . $entity_value} = $self->{statefile_cache}->get(name => $label . '_' . $entity_value); next if (!defined($old_datas->{$label . '_' . $entity_value})); diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 93d6d82e7..d106c5d66 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -371,40 +371,101 @@ sub cache_perf_counters { return 0; } -sub get_entities_host { - my ($obj_esxd, $view_type, $filters, $properties) = @_; +sub search_entities { + my (%options) = @_; + my $properties = ['name']; + my $begin_views = []; + + foreach my $scope (['scope_datacenter', 'Datacenter'], ['scope_cluster', 'ClusterComputeResource'], ['scope_host', 'HostSystem']) { + if (defined($options{command}->{$$scope[0]}) && $options{command}->{$$scope[0]} ne '') { + my $filters = { name => qr/$options{command}->{$$scope[0]}/ }; + if (scalar(@$begin_views) > 0) { + my $temp_views = []; + while ((my $view = shift @$begin_views)) { + my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $$scope[1], properties => $properties, filter => $filters, + begin_entity => $view, output_message => 0); + next if ($status == 0); + return undef if ($status == -1); + push @$temp_views, @$views; + } + + if (scalar(@$temp_views) == 0) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Cannot find '$$scope[1]' object"); + return undef; + } + push @$begin_views, @$temp_views; + } else { + my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $$scope[1], properties => $properties, filter => $filters); + # We quit. No scope find + return undef if ($status <= 0); + push @$begin_views, @$views; + } + } + } + + if (scalar(@$begin_views) > 0) { + my $results = []; + foreach my $view (@$begin_views) { + my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, + begin_entity => $view, output_message => 0); + next if ($status == 0); + return undef if ($status == -1); + push @$results, @$views; + } + if (scalar(@$results) == 0) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Cannot find '$options{view_type}' object"); + return undef; + } + return $results; + } else { + my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); + return $views; + } +} + +sub find_entity_views { + my (%options) = @_; my $entity_views; eval { - $entity_views = $obj_esxd->{session1}->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + if (defined($options{begin_entity})) { + $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, begin_entity => $options{begin_entity}); + } else { + $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); + } }; if ($@) { - $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@"); + $options{connector}->{logger}->writeLogError("'" . $options{connector}->{whoaim} . "' $@"); eval { - $entity_views = $obj_esxd->{session1}->find_entity_views(view_type => $view_type, properties => $properties, filter => $filters); + if (defined($options{begin_entity})) { + $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, begin_entity => $options{begin_entity}); + } else { + $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); + } }; if ($@) { - vmware_error($obj_esxd, $@); - return undef; + vmware_error($options{connector}, $@); + return (-1, undef); } } - if (!@$entity_views) { + if (!defined($entity_views) || scalar(@$entity_views) == 0) { my $status = 0; - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Object $view_type does not exist"); - return undef; + if (!defined($options{output_message}) || $options{output_message} != 0) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Cannot find '$options{view_type}' object"); + } + return (0, 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; + return (1, $entity_views); } sub performance_errors { diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index b67d2bfdb..fcbdf9ccc 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -43,6 +43,7 @@ my @load_modules = ( 'centreon::esxd::cmdgetmap', 'centreon::esxd::cmdhealthhost', 'centreon::esxd::cmdlimitvm', + 'centreon::esxd::cmdlistdatacenters', 'centreon::esxd::cmdlistdatastores', 'centreon::esxd::cmdlistnichost', 'centreon::esxd::cmdmemhost', From 070176421436abffafa05ddabdd960ff8529f14d Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Apr 2015 11:39:05 +0200 Subject: [PATCH 124/447] Fix variable names (better) --- .../vmware/src/centreon/esxd/cmdalarmhost.pm | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm index 522991d92..72bf58837 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm @@ -92,12 +92,12 @@ sub run { my $alarmMgr = centreon::esxd::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; - my $dc_alarms = {}; + my $host_alarms = {}; my $new_datas = {}; - foreach my $datacenter_view (@$result) { - $dc_alarms->{$datacenter_view->name} = { red => 0, yellow => 0, alarms => {} }; - next if (!defined($datacenter_view->triggeredAlarmState)); - foreach(@{$datacenter_view->triggeredAlarmState}) { + foreach my $host_view (@$result) { + $host_alarms->{$host_view->name} = { red => 0, yellow => 0, alarms => {} }; + next if (!defined($host_view->triggeredAlarmState)); + foreach(@{$host_view->triggeredAlarmState}) { next if ($_->overallStatus->val !~ /(red|yellow)/i); if (defined($self->{filter_time}) && $self->{filter_time} ne '') { my $time_sec = Date::Parse::str2time($_->time); @@ -109,11 +109,11 @@ sub run { my $entity = centreon::esxd::common::get_view($self->{connector}, $_->entity, ['name']); my $alarm = centreon::esxd::common::get_view($self->{connector}, $_->alarm, ['info']); - $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, + $host_alarms->{$host_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, time => $_->time, name => $alarm->info->name, description => $alarm->info->description, status => $_->overallStatus->val}; - $dc_alarms->{$datacenter_view->name}->{$_->overallStatus->val}++; + $host_alarms->{$host_view->name}->{$_->overallStatus->val}++; $total_alarms->{$_->overallStatus->val}++; } } @@ -130,27 +130,27 @@ sub run { short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{red})); } - foreach my $dc_name (keys %{$dc_alarms}) { - $self->{manager}->{output}->output_add(long_msg => sprintf("Checking host %s", $dc_name)); + foreach my $host_name (keys %{$host_alarms}) { + $self->{manager}->{output}->output_add(long_msg => sprintf("Checking host %s", $host_name)); $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", - $dc_alarms->{$dc_name}->{yellow}, $dc_alarms->{$dc_name}->{red})); - foreach my $alert (keys %{$dc_alarms->{$dc_name}->{alarms}}) { + $host_alarms->{$host_name}->{yellow}, $host_alarms->{$host_name}->{red})); + foreach my $alert (keys %{$host_alarms->{$host_name}->{alarms}}) { $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s", - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{status}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{name}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{time}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{type}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{description} + $host_alarms->{$host_name}->{alarms}->{$alert}->{status}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{name}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{time}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{type}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{description} )); } my $extra_label = ''; - $extra_label = '_' . $dc_name if ($multiple == 1); + $extra_label = '_' . $host_name if ($multiple == 1); $self->{manager}->{output}->perfdata_add(label => 'alarm_warning' . $extra_label, - value => $dc_alarms->{$dc_name}->{yellow}, + value => $host_alarms->{$host_name}->{yellow}, min => 0); $self->{manager}->{output}->perfdata_add(label => 'alarm_critical' . $extra_label, - value => $dc_alarms->{$dc_name}->{red}, + value => $host_alarms->{$host_name}->{red}, min => 0); } From b2318c2310a32f0b87360b17ff9a9b03496866fa Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Apr 2015 14:38:27 +0200 Subject: [PATCH 125/447] + Add command status-vm in connector --- .../vmware/src/centreon/esxd/cmdstatusvm.pm | 118 ++++++++++++++++++ .../src/centreon/script/centreonesxd.pm | 1 + 2 files changed, 119 insertions(+) create mode 100644 connectors/vmware/src/centreon/esxd/cmdstatusvm.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm b/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm new file mode 100644 index 000000000..410fb77a7 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm @@ -0,0 +1,118 @@ + +package centreon::esxd::cmdstatusvm; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'statusvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{connector} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + + if (defined($self->{vm_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; + } elsif (!defined($self->{vm_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{vm_hostname}/; + } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } + my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + my %overallStatus = ( + 'gray' => 'status is unknown', + 'green' => 'is OK', + 'red' => 'has a problem', + 'yellow' => 'might have a problem', + ); + my %overallStatusReturn = ( + 'gray' => 'UNKNOWN', + 'green' => 'OK', + 'red' => 'CRITICAL', + 'yellow' => 'WARNING' + ); + + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All virtual machines are ok")); + } + + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + + my $status_vm = $entity_view->{'summary.overallStatus'}->val; + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_vm})); + + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $overallStatusReturn{$status_vm}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $overallStatusReturn{$status_vm}, + short_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_vm})); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index fcbdf9ccc..ec59326f2 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -52,6 +52,7 @@ my @load_modules = ( 'centreon::esxd::cmdnethost', 'centreon::esxd::cmdsnapshotvm', 'centreon::esxd::cmdstatushost', + 'centreon::esxd::cmdstatusvm', 'centreon::esxd::cmdswaphost', 'centreon::esxd::cmdswapvm', 'centreon::esxd::cmdthinprovisioningvm', From a10693df4d07eabfda6ff0231d8c4a222c6ff170 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Apr 2015 14:49:38 +0200 Subject: [PATCH 126/447] Fix status vm --- connectors/vmware/src/centreon/esxd/cmdstatusvm.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm b/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm index 410fb77a7..57c97af8d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm @@ -69,10 +69,10 @@ sub run { if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters{'config.annotation'} = qr/$self->{filter_description}/; } + my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); From fad21e12b653abfa684404772e4e72891c54f6e4 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 29 Apr 2015 17:13:28 +0200 Subject: [PATCH 127/447] Fix new mode --- connectors/vmware/src/centreon/esxd/cmdstatusvm.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm b/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm index 57c97af8d..43ab81f18 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm @@ -102,6 +102,7 @@ sub run { hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, + nocheck_ps => 1, multiple => $multiple) == 0); my $status_vm = $entity_view->{'summary.overallStatus'}->val; From dcee7cb0e62b176ad8872beaa531ab880aa309c1 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 5 May 2015 22:48:51 +0200 Subject: [PATCH 128/447] Fix issue with traffic perfdatas --- .../vmware/src/centreon/esxd/cmdnethost.pm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdnethost.pm b/connectors/vmware/src/centreon/esxd/cmdnethost.pm index 8612fcb1d..dcbd90c43 100644 --- a/connectors/vmware/src/centreon/esxd/cmdnethost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdnethost.pm @@ -85,7 +85,7 @@ sub run { } my %filters = (); - my $multiple = 0; + my ($multiple, $number_nic) = (0, 0); if (defined($self->{esx_hostname}) && !defined($self->{filter})) { $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; } elsif (!defined($self->{esx_hostname})) { @@ -150,6 +150,7 @@ sub run { next; } $filter_ok = 1; + $number_nic++; if (defined($_->linkSpeed)) { $pnic_def_up->{$entity_view->{mo_ref}->{value}}->{$_->device} = $_->linkSpeed->speedMb; push @$instances, $_->device; @@ -159,12 +160,12 @@ sub run { } if ($filter_ok == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("%s can't get physical nic with filter '%s'. (or physical nic not in a 'vswitch' or 'dvswitch'", + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("%s can't get physical nic with filter '%s'. (or physical nic not in a 'vswitch' or 'dvswitch'", $entity_view->{name}, $self->{nic_name})); - next; + next; } - if (scalar(@${instances}) == 0 && + if (scalar(@$instances) == 0 && ($multiple == 0 || ($multiple == 1 && !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1)))) { $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, short_msg => sprintf("%s Link(s) '%s' is(are) down", @@ -194,7 +195,7 @@ sub run { foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; if (scalar(keys %{$pnic_def_down->{$entity_value}}) > 0 && - ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1))) { + (($multiple == 0 && $number_nic == 1) || !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1))) { $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, short_msg => sprintf("%s Link(s) '%s' is(are) down", $entity_view->{name}, join("','", keys %{$pnic_def_down->{$entity_value}}))); @@ -223,13 +224,14 @@ sub run { $out_value . $out_unit, $out_prct); $long_msg .= $long_msg_append . $output; $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0 && $number_nic == 1)) { $short_msg .= $short_msg_append . $output; $short_msg_append = ', '; } my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $extra_label .= '_' . $_ if ($number_nic > 1); + $extra_label .= '_' . $entity_view->{name} if ($multiple == 1); $self->{manager}->{output}->perfdata_add(label => 'traffic_in' . $extra_label, unit => 'b/s', value => sprintf("%.2f", $traffic_in), warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-in', total => $interface_speed), From 390eeb6aee807ddb743bd4f2a92a232169d9d5bb Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 5 May 2015 23:35:45 +0200 Subject: [PATCH 129/447] + Add a command to get host times (for debug) --- .../vmware/src/centreon/esxd/cmdtimehost.pm | 106 ++++++++++++++++++ .../src/centreon/script/centreonesxd.pm | 1 + 2 files changed, 107 insertions(+) create mode 100644 connectors/vmware/src/centreon/esxd/cmdtimehost.pm diff --git a/connectors/vmware/src/centreon/esxd/cmdtimehost.pm b/connectors/vmware/src/centreon/esxd/cmdtimehost.pm new file mode 100644 index 000000000..99acc10d2 --- /dev/null +++ b/connectors/vmware/src/centreon/esxd/cmdtimehost.pm @@ -0,0 +1,106 @@ + +package centreon::esxd::cmdtimehost; + +use strict; +use warnings; +use centreon::esxd::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'timehost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{connector} = $options{connector}; +} + +sub run { + my $self = shift; + + if ($self->{connector}->{module_date_parse_loaded} == 0) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Need to install Date::Parse CPAN Module"); + return ; + } + + my %filters = (); + my $multiple = 0; + + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'configManager.dateTimeSystem', 'runtime.connectionState'); + + my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + return if (!defined($result)); + + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => 'Time Host(s):'); + my @host_array = (); + foreach my $entity_view (@$result) { + if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->{val}) == 0) { + $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s' is disconnected", + $entity_view->{name})); + next; + } + if (defined($entity_view->{'configManager.dateTimeSystem'})) { + push @host_array, $entity_view->{'configManager.dateTimeSystem'}; + } + } + + @properties = (); + my $result2 = centreon::esxd::common::get_views($self->{connector}, \@host_array, \@properties); + return if (!defined($result2)); + + foreach my $entity_view (@$result) { + my $host_dts_value = $entity_view->{'configManager.dateTimeSystem'}->{value}; + foreach my $host_dts_view (@$result2) { + if ($host_dts_view->{mo_ref}->{value} eq $host_dts_value) { + my $time = $host_dts_view->QueryDateTime(); + my $timestamp = Date::Parse::str2time($time); + $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s': unix timestamp %s, date: %s", + $entity_view->{name}, $timestamp, $time)); + last; + } + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index ec59326f2..e88114b2c 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -56,6 +56,7 @@ my @load_modules = ( 'centreon::esxd::cmdswaphost', 'centreon::esxd::cmdswapvm', 'centreon::esxd::cmdthinprovisioningvm', + 'centreon::esxd::cmdtimehost', 'centreon::esxd::cmdtoolsvm', 'centreon::esxd::cmduptimehost', 'centreon::esxd::cmdvmoperationcluster', From 38b90379fc8f0e82e4700780dffbff6af978730b Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 15 Jun 2015 15:08:29 +0200 Subject: [PATCH 130/447] + manage esx 3.x for traffic --- connectors/vmware/src/centreon/esxd/cmdnethost.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/esxd/cmdnethost.pm b/connectors/vmware/src/centreon/esxd/cmdnethost.pm index dcbd90c43..3cf5c1293 100644 --- a/connectors/vmware/src/centreon/esxd/cmdnethost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdnethost.pm @@ -93,7 +93,10 @@ sub run { } else { $filters{name} = qr/$self->{esx_hostname}/; } - my @properties = ('name', 'config.network.pnic', 'runtime.connectionState', 'config.network.vswitch', 'config.network.proxySwitch'); + my @properties = ('name', 'config.network.pnic', 'runtime.connectionState', 'config.network.vswitch'); + if (!defined($self->{no_proxyswitch})) { + push @properties, 'config.network.proxySwitch'; + } my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); From fa6ff005661d6015322842409f02153758e41260 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 17 Jul 2015 13:30:46 +0200 Subject: [PATCH 131/447] + fix some filter missing --- connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm | 4 ++++ connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm index 99bbd96e5..81c89d4c2 100644 --- a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm @@ -87,6 +87,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'config.hardware.device', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm index 47e16be82..45dc72316 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm @@ -96,6 +96,10 @@ sub run { } else { $filters{name} = qr/$self->{vm_hostname}/; } + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters{'config.annotation'} = qr/$self->{filter_description}/; + } + my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; From ce355499721c24ff66cc1a8b7ed68d479aedcd1c Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 20 Jul 2015 13:44:58 +0200 Subject: [PATCH 132/447] + Version 2.0 connector vmware --- connectors/vmware/centreon_esxd | 39 ---- connectors/vmware/centreon_esxd-sysconfig | 2 - .../vmware/doc/en/exploitation/index.rst | 21 +- .../vmware/doc/en/installation/index.rst | 192 +++++++++++---- .../vmware/doc/fr/exploitation/index.rst | 14 +- .../vmware/doc/fr/installation/index.rst | 191 +++++++++++---- .../config/centreon_vmware-conf.pm} | 2 +- .../redhat/centreon_vmware-init} | 22 +- .../redhat/centreon_vmware-sysconfig | 2 + .../{centreonesxd.pm => centreon_vmware.pm} | 221 ++++++++++-------- .../{esxd => vmware}/cmdalarmdatacenter.pm | 31 ++- .../centreon/{esxd => vmware}/cmdalarmhost.pm | 31 ++- .../{esxd => vmware}/cmdcountvmhost.pm | 31 ++- .../centreon/{esxd => vmware}/cmdcpuhost.pm | 37 ++- .../src/centreon/{esxd => vmware}/cmdcpuvm.pm | 41 +++- .../{esxd => vmware}/cmddatastorehost.pm | 37 ++- .../{esxd => vmware}/cmddatastoreio.pm | 35 ++- .../{esxd => vmware}/cmddatastoreiops.pm | 39 +++- .../{esxd => vmware}/cmddatastoresnapshot.pm | 31 ++- .../{esxd => vmware}/cmddatastoreusage.pm | 27 ++- .../{esxd => vmware}/cmddatastorevm.pm | 43 ++-- .../centreon/{esxd => vmware}/cmdgetmap.pm | 27 ++- .../{esxd => vmware}/cmdhealthhost.pm | 27 ++- .../centreon/{esxd => vmware}/cmdlimitvm.pm | 31 ++- .../{esxd => vmware}/cmdlistdatacenters.pm | 25 +- .../{esxd => vmware}/cmdlistdatastores.pm | 25 +- .../{esxd => vmware}/cmdlistnichost.pm | 25 +- .../{esxd => vmware}/cmdmaintenancehost.pm | 27 ++- .../centreon/{esxd => vmware}/cmdmemhost.pm | 35 ++- .../src/centreon/{esxd => vmware}/cmdmemvm.pm | 43 ++-- .../centreon/{esxd => vmware}/cmdnethost.pm | 35 ++- .../{esxd => vmware}/cmdsnapshotvm.pm | 31 ++- .../{esxd => vmware}/cmdstatushost.pm | 27 ++- .../centreon/{esxd => vmware}/cmdstatusvm.pm | 27 ++- .../centreon/{esxd => vmware}/cmdswaphost.pm | 35 ++- .../centreon/{esxd => vmware}/cmdswapvm.pm | 37 ++- .../{esxd => vmware}/cmdthinprovisioningvm.pm | 31 ++- .../centreon/{esxd => vmware}/cmdtimehost.pm | 29 ++- .../centreon/{esxd => vmware}/cmdtoolsvm.pm | 31 ++- .../{esxd => vmware}/cmduptimehost.pm | 27 ++- .../{esxd => vmware}/cmdvmoperationcluster.pm | 31 ++- .../src/centreon/{esxd => vmware}/common.pm | 79 ++++--- .../centreon/{esxd => vmware}/connector.pm | 49 ++-- connectors/vmware/src/centreon_vmware.pl | 56 +++++ 44 files changed, 1333 insertions(+), 546 deletions(-) delete mode 100644 connectors/vmware/centreon_esxd delete mode 100644 connectors/vmware/centreon_esxd-sysconfig rename connectors/vmware/{centreon_esxd-conf.pm => packaging/config/centreon_vmware-conf.pm} (90%) rename connectors/vmware/{centreon_esxd-init => packaging/redhat/centreon_vmware-init} (78%) create mode 100644 connectors/vmware/packaging/redhat/centreon_vmware-sysconfig rename connectors/vmware/src/centreon/script/{centreonesxd.pm => centreon_vmware.pm} (62%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdalarmdatacenter.pm (83%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdalarmhost.pm (83%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdcountvmhost.pm (82%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdcpuhost.pm (79%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdcpuvm.pm (80%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmddatastorehost.pm (82%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmddatastoreio.pm (78%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmddatastoreiops.pm (85%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmddatastoresnapshot.pm (82%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmddatastoreusage.pm (86%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmddatastorevm.pm (82%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdgetmap.pm (68%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdhealthhost.pm (87%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdlimitvm.pm (84%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdlistdatacenters.pm (70%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdlistdatastores.pm (73%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdlistnichost.pm (77%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdmaintenancehost.pm (78%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdmemhost.pm (80%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdmemvm.pm (78%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdnethost.pm (87%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdsnapshotvm.pm (84%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdstatushost.pm (75%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdstatusvm.pm (77%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdswaphost.pm (79%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdswapvm.pm (80%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdthinprovisioningvm.pm (79%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdtimehost.pm (70%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdtoolsvm.pm (85%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmduptimehost.pm (83%) rename connectors/vmware/src/centreon/{esxd => vmware}/cmdvmoperationcluster.pm (84%) rename connectors/vmware/src/centreon/{esxd => vmware}/common.pm (88%) rename connectors/vmware/src/centreon/{esxd => vmware}/connector.pm (81%) create mode 100644 connectors/vmware/src/centreon_vmware.pl diff --git a/connectors/vmware/centreon_esxd b/connectors/vmware/centreon_esxd deleted file mode 100644 index aac3e5d2e..000000000 --- a/connectors/vmware/centreon_esxd +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl - -use warnings; -use centreon::script::centreonesxd; -use FindBin; -use lib "$FindBin::Bin"; - -centreon::script::centreonesxd->new()->run(); - -__END__ - -=head1 NAME - -centreon_esxd - a daemon to handle VMWare checks. - -=head1 SYNOPSIS - -centreon_esxd [options] - -=head1 OPTIONS - -=over 8 - -=item B<--config-extra> - -Specify the path to the centreonesxd configuration file (default: /etc/centreon/centreon_esxd.pm). - -=item B<--help> - -Print a brief help message and exits. - -=back - -=head1 DESCRIPTION - -B will connect to ESX and/or VirtualCenter. Use the script 'centreon_esx_client.pl' -to do checks through the daemon. - -=cut diff --git a/connectors/vmware/centreon_esxd-sysconfig b/connectors/vmware/centreon_esxd-sysconfig deleted file mode 100644 index ca1a0880e..000000000 --- a/connectors/vmware/centreon_esxd-sysconfig +++ /dev/null @@ -1,2 +0,0 @@ -# centreon_esxd command line options -OPTIONS="--logfile=/var/log/centreon/centreon_esxd.log --severity=error" \ No newline at end of file diff --git a/connectors/vmware/doc/en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst index 46d57c25f..9e06a9324 100644 --- a/connectors/vmware/doc/en/exploitation/index.rst +++ b/connectors/vmware/doc/en/exploitation/index.rst @@ -5,9 +5,9 @@ Exploitation Generals Principles ------------------- -Centreon-esxd is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter. +Centreon-vmware is a Perl program in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare in order to connect and get back the informations of one (or more) Virtual Center. To do this, it makes a TCP connection with the VirtualCenter. -By default "centreon-esxd" starts at least two processes (named "handle-client" and "handle-vsphere-xxxx") : +By default "centreon-vmware" starts at least two processes (named "handle-client" and "handle-vsphere-xxxx") : *« handle-client »*: *Process waiting for requests of clients.* @@ -25,7 +25,7 @@ Steps of operation : Then, this process gets back the VMWare indicators creating a subprocess per request. -Centreon-esxd necessitates the utilization of one (or more) VirtualCenter (or ESX). +Centreon-vmware necessitates the utilization of one (or more) VirtualCenter (or ESX). This is a example of a distributed architecture : .. image:: ../images/archi.png @@ -33,15 +33,15 @@ This is a example of a distributed architecture : Operating mode -------------- -The "centreon-esxd" program only works in "daemon" mode (a client is needed). +The "centreon-vmware" program only works in "daemon" mode (a client is needed). Connector configuration ----------------------- -The « centreon-esxd » daemon is configured with the « centreon_esxd.pm » configuration file: +The « centreon-vmware » daemon is configured with the « centreon_vmware.pm » configuration file: :: - %centreonesxd_config = ( + %centreon_vmware_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', @@ -53,7 +53,7 @@ The « centreon-esxd » daemon is configured with the « centreon_esxd.pm » In case you have many VirtualCenters, the configuration is (note the use of "," as a separator): :: - %centreonesxd_config = ( + %centreon_vmware_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', @@ -69,12 +69,9 @@ In case you have many VirtualCenters, the configuration is (note the use of "," Troubleshooting --------------- -It is possible to get this kind of errors in the « logs » of « centreon-esxd »: +It is possible to get this kind of errors in the « logs » of « centreon-vmware »: :: ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... -VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. The bug comes from OpenSSL. It should be fix in OpenSSL 1.0.1h (CVE-2010-5298). - -It is necessary to create an incident in case there are too many connections error between the daemon and the VirtualCenter. - +VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. The bug comes from OpenSSL. It should be fix in OpenSSL 1.0.1h (CVE-2010-5298). \ No newline at end of file diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 9b0d6dd86..237e5bc5c 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -8,24 +8,24 @@ Prerequisites Software Recommandations ```````````````````````` -The "centreon-esxd" connector has been only tested on red-hat 6 with rpms. -Installation on other system is possible but is outside the scope of this document (Debian,...). +The "centreon-vmware" connector has been only tested on red-hat 5 and 6 with rpms. +Installation on other system should be possible. ====================== ===================== Software Version ====================== ===================== VMWare SDK Perl 5.1.0-780721 Perl 5.8 -centreon-esxd 1.6.0 -perl-centreon-base 2.5.0 -centreon-plugins-base 1.10 +centreon-vmware 2.0.0 +perl-centreon-base 2.6.0 +centreon-plugins-base 1.11 ZeroMQ 3.x +Perl Date::Parse 1.x Perl ZMQ::LibZMQ3 1.19 Perl ZMQ::Constants 1.04 ====================== ===================== -.. warning:: - The "centreon-esxd" RPMS provided by Merethis is designed to work with Centreon 2.5 (CES 3), it does not work with Centreon 2.4. +How to install from sources is explained in the current documentation. Hardware Recommandations ```````````````````````` @@ -35,18 +35,106 @@ Hardware prerequisites will depend of check numbers. Minimal used resources are * RAM : 512 Mo (May slightly increase with the number of checks). * CPU : same as poller server. -Centreon-esxd Installation - centos/rhel 5 systems -================================================== - -Not tested on centos/rhel 5. There is a problem with Perl ZMQ::LibZMQ3 module. - -Centreon-esxd Installation - centos/rhel 6 systems -================================================== +Centreon-vmware Installation - centos/rhel 5 systems +==================================================== SDK Perl VMWare Installation ```````````````````````````` -The "centreon-esxd" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommandation (only tested with version below). +The "centreon-vmware" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommandation (only tested with version below). + +======================= ===================== ====================== +Dependency Version Repository +======================= ===================== ====================== +perl-libwww-perl 5.805 redhat/centos base +perl-XML-LibXML 1.58 redhat/centos base +perl-Class-MethodMaker 2.18 ces standard +perl-Crypt-SSLeay 0.51 redhat/centos base +perl-SOAP-Lite 0.712 ces standard +perl-UUID 0.04 ces standard +perl-VMware-vSphere 5.1.0-780721.1 ces standard +======================= ===================== ====================== + +Install following dependency:: + + # yum install perl-VMware-vSphere + +Requirements +````````````` + +Following prerequisites are mandatory for « centreon_vmware »: + +* « perl-centreon-base »: module since Centreon 2.5 (repository ces standard) +* « centreon-plugins-base »: in repository ces standard +* « zeromq » and Perl binding: in repository ces standard or EPEL + +Following prerequisites are optional for « centreon_vmware »: + +* « perl-TimeDate »: in repository redhat/centos base + +centreon-vmware Installation with rpm +````````````````````````````````````` + +Install the connector: +:: + + # yum install ces-plugins-Virtualization-VMWare-daemon + +Install the client: +:: + + # yum install ces-plugins-Virtualization-VMWare-client + +centreon-vmware Installation with source +```````````````````````````````````````` + +Download « centreon-vmware » archive, then install :: + + # tar zxvf centreon-vmware-2.0.0.tar.gz + # cd centreon-vmware-2.0.0 + # cp centreon_vmware.pl /usr/bin/ + + # mkdir -p /etc/centreon + # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + # cp contrib/redhat/centreon_vmware-init /etc/init.d/centreon_vmware + # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware + # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl + + # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ + # cp centreon/vmware/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ + # cp centreon/script/centreon_vmware.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ + +Configure "centreon-vmware" daemon to start at boot: +:: + + # chkconfig --level 2345 centreon_vmware on + +Install « perl-centreon-base » dependency: +:: + + # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon + # cd centreon + # cp lib/perl/centreon/script.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/ + # cp -R lib/perl/centreon/common /usr/lib/perl5/vendor_perl/5.8.8/centreon/ + +Install the client: +:: + + # git clone http://git.centreon.com/centreon-plugins.git + # cd centreon-plugins + # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + # cp centreon_plugins.pl /usr/lib/nagios/plugins/ + +Centreon-vmware Installation - centos/rhel 6 systems +==================================================== + +SDK Perl VMWare Installation +```````````````````````````` + +The "centreon-vmware" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommendation (only tested with version below). ======================= ===================== ====================== Dependency Version Repository @@ -56,8 +144,8 @@ perl-XML-LibXML 1.70 redhat/centos base perl-Class-MethodMaker 2.16 redhat/centos base perl-Crypt-SSLeay 0.57 redhat/centos base perl-SOAP-Lite 0.710.10 redhat/centos base -perl-UUID 0.04 centreon plugin-packs -perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs +perl-UUID 0.04 ces standard +perl-VMware-vSphere 5.1.0-780721.1 ces standard ======================= ===================== ====================== Install following dependency: @@ -66,57 +154,71 @@ Install following dependency: root # yum install perl-VMware-vSphere Requirements -``````````````````````````````` +```````````` -Following prerequisites are mandatory for « centreon_esxd »: +Following prerequisites are mandatory for « centreon_vmware »: * « perl-centreon-base »: module since Centreon 2.5 (repository ces standard) -* « centreon-plugins-base »: in repository centreon plugin-packs +* « centreon-plugins-base »: in repository ces standard * « zeromq » and Perl binding: in repository ces standard or EPEL -centreon-esxd Installation with rpm -``````````````````````````````````` +Following prerequisites are optional for « centreon_vmware »: + +* « perl-TimeDate »: in repository redhat/centos base + +centreon-vmware Installation with rpm +````````````````````````````````````` Install the connector: :: - root # yum install ces-plugins-Virtualization-VMWare + # yum install ces-plugins-Virtualization-VMWare-daemon Install the client: :: - root # yum install ces-plugins-Virtualization-VMWare-client + # yum install ces-plugins-Virtualization-VMWare-client -centreon-esxd Installation with source -`````````````````````````````````````` +centreon-vmware Installation with source +```````````````````````````````````````` -Download « centreon-esxd » archive, then install: +Download « centreon-vmware » archive, then install: :: - root # tar zxvf centreon-esxd-1.6.0.tar.gz - root # cd centreon-esxd-1.6.0 - root # cp centreon_esxd /usr/bin/ + # tar zxvf centreon-vmware-2.0.0.tar.gz + # cd centreon-vmware-2.0.0 + # cp centreon_vmware.pl /usr/bin/ - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd + # mkdir -p /etc/centreon + # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + # cp contrib/redhat/centreon_vmware-init /etc/init.d/centreon_vmware + # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware + # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl - root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreon/esxd/* /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreon/script/centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + # mkdir -p /usr/share/perl5/vendor_perl/centreon/vmware/ + # cp centreon/vmware/* /usr/share/perl5/vendor_perl/centreon/vmware/ + # cp centreon/script/centreon_vmware.pm /usr/share/perl5/vendor_perl/centreon/script/ -Configure "centreon-esxd" daemon to start at boot: +Configure "centreon-vmware" daemon to start at boot: :: - root # chkconfig --level 2345 centreon_esxd on + # chkconfig --level 2345 centreon_vmware on +Install « perl-centreon-base » dependency: +:: + + # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon + # cd centreon + # cp lib/perl/centreon/script.pm /usr/share/perl5/vendor_perl/centreon/ + # cp -R lib/perl/centreon/common /usr/share/perl5/vendor_perl/centreon/ + Install the client: :: - root # git clone http://git.centreon.com/centreon-plugins.git - root # cd centreon-plugins - root # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ - root # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ - root # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ - root # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ - root # cp centreon_plugins.pl /usr/lib/nagios/plugins/ + # git clone http://git.centreon.com/centreon-plugins.git + # cd centreon-plugins + # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + # cp centreon_plugins.pl /usr/lib/nagios/plugins/ diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index fe63091c1..faa0fa3a4 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -7,7 +7,7 @@ Principes Généraux Centreon-esxd est un programme Perl chargé de récupérer des indicateurs VMWare. Ce programme utilise le SDK Perl fourni par VMWare afin de se connecter et récupérer les informations d'un (ou plusieurs) VirtualCenter. Pour cela il effectue une connexion TCP avec le(s) VirtualCenter. -Par défaut, « centreon-esxd » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : +Par défaut, « centreon-vmware » lance au moins deux processus (nommé respectivement « handle-client », « handle-vsphere-xxxx ») : *« handle-client »*: *Processus en attente des demandes clientes.* @@ -25,7 +25,7 @@ Voici le fonctionnement : Enfin, ce processus récupère les indicateurs VMWare en créant un sous-processus par demande. -Centreon-esxd nécessite impérativement l'utilisation d'un (ou plusieurs) VirtualCenter (ou ESX). +Centreon-vmware nécessite l'utilisation d'un (ou plusieurs) VirtualCenter (ou ESX). Voici un exemple d'architecture éclaté : @@ -34,15 +34,15 @@ Voici un exemple d'architecture éclaté : Mode de fonctionnement ---------------------- -Le programme « centreon-esxd » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). +Le programme « centreon-vmware » fonctionne uniquement en mode « daemon ». (dans le sens où il ne peut fournir les indicateurs sans l'utilisation d'un client). Configuration du connecteur --------------------------- -Le daemon « centreon-esxd » possède un fichier de configuration « centreon_esxd.pm » de la forme suivante : +Le daemon « centreon-vmware » possède un fichier de configuration « centreon_vmware.pm » de la forme suivante : :: - %centreonesxd_config = ( + %centreon_vmware_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', @@ -54,7 +54,7 @@ L'attribut « vsphere_server » permet de configurer les accès aux différents Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter la "," de séparation) : :: - %centreonesxd_config = ( + %centreon_vmware_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', @@ -77,5 +77,3 @@ Il est possible de retrouver des erreurs de ce type dans les « logs » de « Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. Le bug provient d'OpenSSL. Il devrait être fix dans la version 1.0.1h (CVE-2010-5298). -Il est nécessaire de remonter un problème dans le cas d'un trop grand nombres de déconnexion du daemon au VirtualCenter. - diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index c5028a55c..38686807b 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -8,7 +8,7 @@ Pré-Requis Préconisations logicielles `````````````````````````` -Le connecteur "centreon-esxd" est testé et validé sur red-hat 6 uniquement avec des rpms. +Le connecteur "centreon-vmware" est testé et validé sur red-hat 6 uniquement avec des rpms. L'installation sur d'autres environnements n'est pas exclu mais non présenté dans ce document (Debian, ...). ====================== ===================== @@ -16,16 +16,16 @@ Logiciels Version ====================== ===================== VMWare SDK Perl 5.1.0-780721 Perl 5.8 -centreon-esxd 1.6.0 +centreon-vmware 2.0.0 perl-centreon-base 2.5.0 centreon-plugins-base 1.10 ZeroMQ 3.x +Perl Date::Parse 1.x Perl ZMQ::LibZMQ3 1.19 Perl ZMQ::Constants 1.04 ====================== ===================== -.. warning:: - Le connecteur "centreon-esxd" fourni par Merethis est conçu pour fonctionner Centreon 2.5 (CES 3), il ne fonctionne pas avec Centreon 2.4. +Il est expliqué comment installer par les sources dans ce document. Préconisations matérielles `````````````````````````` @@ -35,18 +35,107 @@ Le matériel nécessaire dépend du nombre de demandes de vérifications. Par d * mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). * CPU : même pré-requis que pour le serveur de collecte. -Installation de centreon-esxd - Environnement centos/rhel 5 -=========================================================== - -Le connecteur n'a pas été testé et validé en centos/rhel 5. - -Installation de centreon-esxd - Environnement centos/rhel 6 -=========================================================== +Installation de centreon-vmware - Environnement centos/rhel 5 +============================================================= Installation du SDK Perl VMWare ``````````````````````````````` -Le connecteur « centreon-esxd » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). +Le connecteur « centreon-vmware » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). + +======================= ===================== ====================== +Dépendance Version Dépôt +======================= ===================== ====================== +perl-libwww-perl 5.805 redhat/centos base +perl-XML-LibXML 1.58 redhat/centos base +perl-Class-MethodMaker 2.18 ces standard +perl-Crypt-SSLeay 0.51 redhat/centos base +perl-SOAP-Lite 0.712 ces standard +perl-UUID 0.04 ces standard +perl-VMware-vSphere 5.1.0-780721.1 ces standard +======================= ===================== ====================== + +Installer la dépendance suivante:: + + # yum install perl-VMware-vSphere + +Pré-requis +`````````` + +Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_vmware »: + +* « perl-centreon-base »: module depuis Centreon 2.5 (dépôt ces standard) +* « centreon-plugins-base »: dépôt ces standard +* « zeromq » and Perl binding: dépôt ces standard ou EPEL + +Les dépendances suivantes sont optionnelles pour le fonctionnement de « centreon_vmware »: + +* « perl-TimeDate »: dépôt redhat/centos base + +Installation de centreon-vmware par rpm +``````````````````````````````````````` + +Installer le connecteur: +:: + + # yum install ces-plugins-Virtualization-VMWare-daemon + +Installer le client: +:: + + # yum install ces-plugins-Virtualization-VMWare-client + +Installation de centreon-vmware par les sources +``````````````````````````````````````````````` + +Télécharger l'archive de « centreon-vmware ». + +Installer les fichiers:: + + # tar zxvf centreon-vmware-2.0.0.tar.gz + # cd centreon-vmware-2.0.0 + # cp centreon_vmware.pl /usr/bin/ + + # mkdir -p /etc/centreon + # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + # cp contrib/redhat/centreon_vmware-init /etc/init.d/centreon_vmware + # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware + # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl + + # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ + # cp centreon/vmware/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ + # cp centreon/script/centreon_vmware.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ + +Activer le daemon « centreon-vmware » au démarrage:: + + # chkconfig --level 2345 centreon_vmware on + +Installer la dépendance « perl-centreon-base »: +:: + + # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon + # cd centreon + # cp lib/perl/centreon/script.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/ + # cp -R lib/perl/centreon/common /usr/lib/perl5/vendor_perl/5.8.8/centreon/ + +Installer le client: +:: + + # git clone http://git.centreon.com/centreon-plugins.git + # cd centreon-plugins + # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + # cp centreon_plugins.pl /usr/lib/nagios/plugins/ + +Installation de centreon-vmware - Environnement centos/rhel 6 +============================================================= + +Installation du SDK Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-vmware » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). ======================= ===================== ====================== Dépendance Version Dépôt @@ -56,72 +145,78 @@ perl-XML-LibXML 1.70 redhat/centos base perl-Class-MethodMaker 2.16 redhat/centos base perl-Crypt-SSLeay 0.57 redhat/centos base perl-SOAP-Lite 0.710.10 redhat/centos base -perl-UUID 0.04 centreon plugin-packs -perl-VMware-vSphere 5.1.0-780721.1 centreon plugin-packs +perl-UUID 0.04 ces standard +perl-VMware-vSphere 5.1.0-780721.1 ces standard ======================= ===================== ====================== Installer la dépendance suivante: :: - root # yum install perl-VMware-vSphere + # yum install perl-VMware-vSphere Pré-requis -``````````````````````````````````````` +`````````` -Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_esxd »: +Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_vmware »: * « perl-centreon-base » : module est présent à partir de Centreon 2.5 (dépôt ces standard) -* « centreon-plugins-base » : présent dans le dépôt centreon plugin-packs +* « centreon-plugins-base » : présent dans le dépôt ces standard * « zeromq » et le binding Perl : présent dans le dépôt ces standard ou EPEL -Installation de centreon-esxd par rpm -````````````````````````````````````` +Les dépendances suivantes sont optionnelles pour le fonctionnement de « centreon_vmware »: + +* « perl-TimeDate »: dépôt redhat/centos base + +Installation de centreon-vmware par rpm +``````````````````````````````````````` Installer le connecteur: :: - root # yum install ces-plugins-Virtualization-VMWare + # yum install ces-plugins-Virtualization-VMWare-daemon Installer le client: :: - root # yum install ces-plugins-Virtualization-VMWare-client + # yum install ces-plugins-Virtualization-VMWare-client -Installation de centreon-esxd par les sources -````````````````````````````````````````````` +Installation de centreon-vmware par les sources +``````````````````````````````````````````````` -Télécharger l'archive de « centreon-esxd ». +Télécharger l'archive de « centreon-vmware ». -Installer les fichiers: +Installer le connecteur: :: - root # tar zxvf centreon-esxd-1.6.0.tar.gz - root # cd centreon-esxd-1.6.0 - root # cp centreon_esxd /usr/bin/ + # tar zxvf centreon-vmware-2.0.0.tar.gz + # cd centreon-vmware-2.0.0 + # cp centreon_vmware.pl /usr/bin/ - root # mkdir -p /etc/centreon - root # cp centreon_esxd-conf.pm /etc/centreon/centreon_esxd.pm - root # cp centreon_esxd-init /etc/init.d/centreon_esxd + # mkdir -p /etc/centreon + # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + # cp contrib/redhat/centreon_vmware-init /etc/init.d/centreon_vmware + # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware + # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl - root # mkdir -p /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreon/esxd/* /usr/share/perl5/vendor_perl/centreon/esxd/ - root # cp centreon/script/centreonesxd.pm /usr/share/perl5/vendor_perl/centreon/script/ + # mkdir -p /usr/share/perl5/vendor_perl/centreon/vmware/ + # cp centreon/vmware/* /usr/share/perl5/vendor_perl/centreon/vmware/ + # cp centreon/script/centreon_vmware.pm /usr/share/perl5/vendor_perl/centreon/script/ -Activer le daemon « centreon-esxd » au démarrage: +Installer la dépendance « perl-centreon-base »: :: - root # chkconfig --level 2345 centreon_esxd on - + # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon + # cd centreon + # cp lib/perl/centreon/script.pm /usr/share/perl5/vendor_perl/centreon/ + # cp -R lib/perl/centreon/common /usr/share/perl5/vendor_perl/centreon/ + Installer le client: :: - root # git clone http://git.centreon.com/centreon-plugins.git - root # cd centreon-plugins - root # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ - root # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ - root # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ - root # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ - root # cp centreon_plugins.pl /usr/lib/nagios/plugins/ - - - + # git clone http://git.centreon.com/centreon-plugins.git + # cd centreon-plugins + # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + # cp centreon_plugins.pl /usr/lib/nagios/plugins/ diff --git a/connectors/vmware/centreon_esxd-conf.pm b/connectors/vmware/packaging/config/centreon_vmware-conf.pm similarity index 90% rename from connectors/vmware/centreon_esxd-conf.pm rename to connectors/vmware/packaging/config/centreon_vmware-conf.pm index a6bd08e1f..f8ffae8cd 100644 --- a/connectors/vmware/centreon_esxd-conf.pm +++ b/connectors/vmware/packaging/config/centreon_vmware-conf.pm @@ -1,5 +1,5 @@ -%centreonesxd_config = ( +%centreon_vmware_config = ( vsphere_server => { 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'XXXXXX', diff --git a/connectors/vmware/centreon_esxd-init b/connectors/vmware/packaging/redhat/centreon_vmware-init similarity index 78% rename from connectors/vmware/centreon_esxd-init rename to connectors/vmware/packaging/redhat/centreon_vmware-init index 40739cf69..dd48e48c6 100644 --- a/connectors/vmware/centreon_esxd-init +++ b/connectors/vmware/packaging/redhat/centreon_vmware-init @@ -1,26 +1,26 @@ #! /bin/bash # -# centreon_esxd Start/Stop the centreon_esxd daemon. +# centreon_vmware Start/Stop the centreon_vmware daemon. # # chkconfig: 2345 80 20 -# description: centreon_esxd is a Centreon program that manage Vpshere Checks -# processname: centreon_esxd -# config: /etc/centreon/centreon_esxd.pm -# pidfile: /var/run/centreon_esxd.pid +# description: centreon_vmware is a Centreon program that manage Vpshere Checks +# processname: centreon_vmware.pl +# config: /etc/centreon/centreon_vmware.pm +# pidfile: /var/run/centreon_vmware.pid # Source function library. . /etc/init.d/functions -binary=/usr/bin/centreon_esxd +binary=/usr/bin/centreon_vmware.pl servicename=$(basename "$0") OPTIONS="" user=root timeout=60 start_timeout=5 -pidfile=/var/run/centreon_esxd.pid +pidfile=/var/run/centreon_vmware.pid -[ -e /etc/sysconfig/centreon_esxd ] && . /etc/sysconfig/centreon_esxd +[ -e /etc/sysconfig/centreon_vmware ] && . /etc/sysconfig/centreon_vmware # Check if we can find the binary. if [ ! -x $binary ]; then @@ -49,9 +49,9 @@ start() { fi if [ "$(id -u -n)" = "$user" ] ; then - daemon ''$binary' '$OPTIONS' > /dev/null 2>&1 &' + daemon --check centreon_vmware ''$binary' '$OPTIONS' > /dev/null 2>&1 &' else - daemon --user $user ''$binary' '$OPTIONS' > /dev/null 2>&1 &' + daemon --user $user --check centreon_vmware ''$binary' '$OPTIONS' > /dev/null 2>&1 &' fi sleep 2 @@ -122,7 +122,7 @@ case "$1" in rhstatus ;; condrestart) - [ -f /var/lock/subsys/centreon_esxd ] && restart || : + [ -f /var/lock/subsys/centreon_vmware ] && restart || : ;; *) echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}" diff --git a/connectors/vmware/packaging/redhat/centreon_vmware-sysconfig b/connectors/vmware/packaging/redhat/centreon_vmware-sysconfig new file mode 100644 index 000000000..0d8a63ddb --- /dev/null +++ b/connectors/vmware/packaging/redhat/centreon_vmware-sysconfig @@ -0,0 +1,2 @@ +# centreon_vmware command line options +OPTIONS="--logfile=/var/log/centreon/centreon_vmware.log --severity=error" \ No newline at end of file diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm similarity index 62% rename from connectors/vmware/src/centreon/script/centreonesxd.pm rename to connectors/vmware/src/centreon/script/centreon_vmware.pm index e88114b2c..c311f9dc0 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -1,6 +1,23 @@ #!/usr/bin/perl +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::script::centreonesxd; +package centreon::script::centreon_vmware; use strict; use warnings; @@ -13,58 +30,58 @@ use Digest::MD5 qw(md5_hex); use POSIX ":sys_wait_h"; use JSON; use centreon::script; -use centreon::esxd::common; -use centreon::esxd::connector; +use centreon::vmware::common; +use centreon::vmware::connector; -my ($centreonesxd, $frontend); +my ($centreon_vmware, $frontend); BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; } use base qw(centreon::script); -use vars qw(%centreonesxd_config); +use vars qw(%centreon_vmware_config); -my $VERSION = "1.6.0"; +my $VERSION = "2.0.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( - 'centreon::esxd::cmdalarmdatacenter', - 'centreon::esxd::cmdalarmhost', - 'centreon::esxd::cmdcountvmhost', - 'centreon::esxd::cmdcpuhost', - 'centreon::esxd::cmdcpuvm', - 'centreon::esxd::cmddatastoreio', - 'centreon::esxd::cmddatastoreiops', - 'centreon::esxd::cmddatastorehost', - 'centreon::esxd::cmddatastoresnapshot', - 'centreon::esxd::cmddatastorevm', - 'centreon::esxd::cmddatastoreusage', - 'centreon::esxd::cmdgetmap', - 'centreon::esxd::cmdhealthhost', - 'centreon::esxd::cmdlimitvm', - 'centreon::esxd::cmdlistdatacenters', - 'centreon::esxd::cmdlistdatastores', - 'centreon::esxd::cmdlistnichost', - 'centreon::esxd::cmdmemhost', - 'centreon::esxd::cmdmaintenancehost', - 'centreon::esxd::cmdmemvm', - 'centreon::esxd::cmdnethost', - 'centreon::esxd::cmdsnapshotvm', - 'centreon::esxd::cmdstatushost', - 'centreon::esxd::cmdstatusvm', - 'centreon::esxd::cmdswaphost', - 'centreon::esxd::cmdswapvm', - 'centreon::esxd::cmdthinprovisioningvm', - 'centreon::esxd::cmdtimehost', - 'centreon::esxd::cmdtoolsvm', - 'centreon::esxd::cmduptimehost', - 'centreon::esxd::cmdvmoperationcluster', + 'centreon::vmware::cmdalarmdatacenter', + 'centreon::vmware::cmdalarmhost', + 'centreon::vmware::cmdcountvmhost', + 'centreon::vmware::cmdcpuhost', + 'centreon::vmware::cmdcpuvm', + 'centreon::vmware::cmddatastoreio', + 'centreon::vmware::cmddatastoreiops', + 'centreon::vmware::cmddatastorehost', + 'centreon::vmware::cmddatastoresnapshot', + 'centreon::vmware::cmddatastorevm', + 'centreon::vmware::cmddatastoreusage', + 'centreon::vmware::cmdgetmap', + 'centreon::vmware::cmdhealthhost', + 'centreon::vmware::cmdlimitvm', + 'centreon::vmware::cmdlistdatacenters', + 'centreon::vmware::cmdlistdatastores', + 'centreon::vmware::cmdlistnichost', + 'centreon::vmware::cmdmemhost', + 'centreon::vmware::cmdmaintenancehost', + 'centreon::vmware::cmdmemvm', + 'centreon::vmware::cmdnethost', + 'centreon::vmware::cmdsnapshotvm', + 'centreon::vmware::cmdstatushost', + 'centreon::vmware::cmdstatusvm', + 'centreon::vmware::cmdswaphost', + 'centreon::vmware::cmdswapvm', + 'centreon::vmware::cmdthinprovisioningvm', + 'centreon::vmware::cmdtimehost', + 'centreon::vmware::cmdtoolsvm', + 'centreon::vmware::cmduptimehost', + 'centreon::vmware::cmdvmoperationcluster', ); sub new { my $class = shift; - my $self = $class->SUPER::new("centreonesxd", + my $self = $class->SUPER::new("centreon_vmware", centreon_db_conn => 0, centstorage_db_conn => 0, noconfig => 1 @@ -75,7 +92,7 @@ sub new { "config-extra=s" => \$self->{opt_extra}, ); - %{$self->{centreonesxd_default_config}} = + %{$self->{centreon_vmware_default_config}} = ( credstore_use => 0, credstore_file => '/root/.vmware/credstore/vicredentials.xml', @@ -118,7 +135,7 @@ sub init { $SIG{__DIE__} = undef; if (!defined($self->{opt_extra})) { - $self->{opt_extra} = "/etc/centreon/centreon_esxd.pm"; + $self->{opt_extra} = "/etc/centreon/centreon_vmware.pm"; } if (-f $self->{opt_extra}) { require $self->{opt_extra}; @@ -126,14 +143,14 @@ sub init { $self->{logger}->writeLogInfo("Can't find extra config file $self->{opt_extra}"); } - $self->{centreonesxd_config} = {%{$self->{centreonesxd_default_config}}, %centreonesxd_config}; + $self->{centreon_vmware_config} = {%{$self->{centreon_vmware_default_config}}, %centreon_vmware_config}; ##### Load modules $self->load_module(@load_modules); ##### credstore check ##### - if (defined($self->{centreonesxd_config}->{credstore_use}) && defined($self->{centreonesxd_config}->{credstore_file}) && - $self->{centreonesxd_config}->{credstore_use} == 1 && -e "$self->{centreonesxd_config}->{credstore_file}") { + if (defined($self->{centreon_vmware_config}->{credstore_use}) && defined($self->{centreon_vmware_config}->{credstore_file}) && + $self->{centreon_vmware_config}->{credstore_use} == 1 && -e "$self->{centreon_vmware_config}->{credstore_file}") { eval 'require VMware::VICredStore'; if ($@) { $self->{logger}->writeLogError("Could not load module VMware::VICredStore"); @@ -141,7 +158,7 @@ sub init { } require VMware::VICredStore; - if (VMware::VICredStore::init(filename => $self->{centreonesxd_config}->{credstore_file}) == 0) { + if (VMware::VICredStore::init(filename => $self->{centreon_vmware_config}->{credstore_file}) == 0) { $self->{logger}->writeLogError("Credstore init failed: $@"); exit(1); } @@ -149,13 +166,13 @@ sub init { ### # Get password ### - foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { - my $lpassword = VMware::VICredStore::get_password(server => $_, username => $self->{centreonesxd_config}->{vsphere_server}->{$_}->{username}); + foreach (keys %{$self->{centreon_vmware_config}->{vsphere_server}}) { + my $lpassword = VMware::VICredStore::get_password(server => $_, username => $self->{centreon_vmware_config}->{vsphere_server}->{$_}->{username}); if (!defined($lpassword)) { - $self->{logger}->writeLogError("Can't get password for couple host='" . $_ . "', username='" . $self->{centreonesxd_config}->{vsphere_server}->{$_}->{username} . "' : $@"); + $self->{logger}->writeLogError("Can't get password for couple host='" . $_ . "', username='" . $self->{centreon_vmware_config}->{vsphere_server}->{$_}->{username} . "' : $@"); exit(1); } - $self->{centreonesxd_config}->{vsphere_server}->{$_}->{password} = $lpassword; + $self->{centreon_vmware_config}->{vsphere_server}->{$_}->{password} = $lpassword; } } @@ -247,15 +264,15 @@ sub verify_child_vsphere { if ($self->{stop} == 0) { $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "'???!! we relaunch it!!!"); - if ($self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{dynamic} == 0) { + if ($self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{dynamic} == 0) { $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}, dynamic => 0); } else { $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' is dead. But we don't relaunch it (dynamic sub-process)"); - delete $self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}; + delete $self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}; } } else { $self->{logger}->writeLogInfo("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' dead ???!!"); - $self->{centreonesxd_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{running} = 0; + $self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{running} = 0; } delete $self->{childs_vpshere_pid}->{$_}; @@ -263,14 +280,14 @@ sub verify_child_vsphere { } my $count = 0; - foreach (keys %{$self->{centreonesxd_config}->{vsphere_server}}) { - if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{running} == 1) { + foreach (keys %{$self->{centreon_vmware_config}->{vsphere_server}}) { + if ($self->{centreon_vmware_config}->{vsphere_server}->{$_}->{running} == 1) { $count++; } - if ($self->{centreonesxd_config}->{vsphere_server}->{$_}->{dynamic} == 1 && - time() - $self->{centreonesxd_config}->{dynamic_timeout_kill} > $self->{centreonesxd_config}->{vsphere_server}->{$_}->{last_request}) { + if ($self->{centreon_vmware_config}->{vsphere_server}->{$_}->{dynamic} == 1 && + time() - $self->{centreon_vmware_config}->{dynamic_timeout_kill} > $self->{centreon_vmware_config}->{vsphere_server}->{$_}->{last_request}) { $self->{logger}->writeLogError("Send TERM signal for process '" . $_ . "': too many times without requests. We clean it."); - kill('TERM', $self->{centreonesxd_config}->{vsphere_server}->{$_}->{pid}); + kill('TERM', $self->{centreon_vmware_config}->{vsphere_server}->{$_}->{pid}); } } @@ -280,19 +297,19 @@ sub verify_child_vsphere { sub waiting_ready { my ($self, %options) = @_; - return 1 if ($self->{centreonesxd_config}->{vsphere_server}->{$options{container}}->{ready} == 1); + return 1 if ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 1); my $time = time(); # We wait 10 seconds - while ($self->{centreonesxd_config}->{vsphere_server}->{$options{container}}->{ready} == 0 && + while ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 0 && time() - $time < 10) { zmq_poll($self->{poll}, 5000); } - if ($self->{centreonesxd_config}->{vsphere_server}->{$options{container}}->{ready} == 0) { + if ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 0) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "connector still not ready."); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return 0; } @@ -306,26 +323,26 @@ sub request_dynamic { !defined($options{result}->{vsphere_password}) || $options{result}->{vsphere_password} eq '') { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Please set vsphere username or password"); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } my $container = md5_hex($options{result}->{vsphere_address} . $options{result}->{vsphere_username} . $options{result}->{vsphere_password}); # Need to create fork - if (!defined($self->{centreonesxd_config}->{vsphere_server}->{$container})) { - $self->{centreonesxd_config}->{vsphere_server}->{$container} = { url => 'https://' . $options{result}->{vsphere_address} . '/sdk', + if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$container})) { + $self->{centreon_vmware_config}->{vsphere_server}->{$container} = { url => 'https://' . $options{result}->{vsphere_address} . '/sdk', username => $options{result}->{vsphere_username}, password => $options{result}->{vsphere_password}, last_request => time() }; $self->{logger}->writeLogError(sprintf("Dynamic creation: identity = %s [address: %s] [username: %s] [password: %s]", $container, $options{result}->{vsphere_address}, $options{result}->{vsphere_username}, $options{result}->{vsphere_password})); - $centreonesxd->create_vsphere_child(vsphere_name => $container, dynamic => 1); + $centreon_vmware->create_vsphere_child(vsphere_name => $container, dynamic => 1); } return if ($self->waiting_ready(container => $container, manager => $options{manager}, identity => $options{identity}) == 0); - $self->{centreonesxd_config}->{vsphere_server}->{$container}->{last_request} = time(); + $self->{centreon_vmware_config}->{vsphere_server}->{$container}->{last_request} = time(); my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; zmq_sendmsg($frontend, "server-" . $container, $flag); zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); @@ -342,24 +359,24 @@ sub request { if ($@) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Cannot decode json result: $@"); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } if ($result->{command} eq 'stats') { - centreon::esxd::common::stats_info(manager => $options{manager}, + centreon::vmware::common::stats_info(manager => $options{manager}, counters => $self->{counter_stats}); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } if (!defined($self->{modules_registry}->{$result->{command}})) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Unknown method name '$result->{command}'"); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } if ($self->{modules_registry}->{$result->{command}}->checkArgs(manager => $options{manager}, arguments => $result)) { - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } @@ -369,10 +386,10 @@ sub request { return ; } - if (!defined($self->{centreonesxd_config}->{vsphere_server}->{$result->{container}})) { + if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$result->{container}})) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Unknown container name '$result->{container}'"); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } @@ -401,7 +418,7 @@ sub repserver { $result->{plugin}->{name} =~ /^client-(.*)$/; my $identity = 'client-' . pack('H*', $1); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $identity, stdout => $options{data}); } @@ -414,19 +431,19 @@ sub router_event { my $data = zmq_msg_data($message); - my $manager = centreon::esxd::common::init_response(); - if ($centreonesxd->{stop} != 0) { + my $manager = centreon::vmware::common::init_response(); + if ($centreon_vmware->{stop} != 0) { # We quit so we say we're leaving ;) $manager->{output}->output_add(severity => 'UNKNOWN', short_msg => 'Daemon is restarting/stopping...'); - centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $identity); + centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $identity); } elsif ($data =~ /^REQCLIENT\s+(.*)$/msi) { - $centreonesxd->request(identity => $identity, data => $1, manager => $manager); + $centreon_vmware->request(identity => $identity, data => $1, manager => $manager); } elsif ($data =~ /^RESPSERVER2\s+(.*)$/msi) { - $centreonesxd->repserver(data => $1, manager => $manager); + $centreon_vmware->repserver(data => $1, manager => $manager); } elsif ($data =~ /^READY/msi) { $identity =~ /server-(.*)/; - $centreonesxd->{centreonesxd_config}->{vsphere_server}->{$1}->{ready} = 1; + $centreon_vmware->{centreon_vmware_config}->{vsphere_server}->{$1}->{ready} = 1; } my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); @@ -438,24 +455,24 @@ sub create_vsphere_child { my ($self, %options) = @_; $self->{whoaim} = $options{vsphere_name}; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 0; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{ready} = 0; + $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 0; + $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{ready} = 0; $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); my $child_vpshere_pid = fork(); if ($child_vpshere_pid == 0) { - my $connector = centreon::esxd::connector->new(name => $self->{whoaim}, + my $connector = centreon::vmware::connector->new(name => $self->{whoaim}, modules_registry => $self->{modules_registry}, module_date_parse_loaded => $self->{module_date_parse_loaded}, - config => $self->{centreonesxd_config}, + config => $self->{centreon_vmware_config}, logger => $self->{logger}); $connector->run(); exit(0); } $self->{childs_vpshere_pid}->{$child_vpshere_pid} = $self->{whoaim}; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 1; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{dynamic} = $options{dynamic}; - $self->{centreonesxd_config}->{vsphere_server}->{$self->{whoaim}}->{pid} = $child_vpshere_pid; + $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 1; + $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{dynamic} = $options{dynamic}; + $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{pid} = $child_vpshere_pid; } sub bind_ipc { @@ -477,34 +494,34 @@ sub bind_ipc { } sub run { - $centreonesxd = shift; + $centreon_vmware = shift; - $centreonesxd->SUPER::run(); - $centreonesxd->{logger}->redirect_output(); + $centreon_vmware->SUPER::run(); + $centreon_vmware->{logger}->redirect_output(); - $centreonesxd->{logger}->writeLogDebug("centreonesxd launched...."); - $centreonesxd->{logger}->writeLogDebug("PID: $$"); + $centreon_vmware->{logger}->writeLogDebug("centreon_vmware launched...."); + $centreon_vmware->{logger}->writeLogDebug("PID: $$"); my $context = zmq_init(); $frontend = zmq_socket($context, ZMQ_ROUTER); if (!defined($frontend)) { - $centreonesxd->{logger}->writeLogError("Can't setup server: $!"); + $centreon_vmware->{logger}->writeLogError("Can't setup server: $!"); exit(1); } zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard zmq_bind($frontend, 'tcp://*:5700'); - $centreonesxd->bind_ipc(socket => $frontend, ipc_file => '/tmp/centreonesxd/routing.ipc'); + $centreon_vmware->bind_ipc(socket => $frontend, ipc_file => '/tmp/centreon_vmware/routing.ipc'); - foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { - $centreonesxd->{counter_stats}->{$_} = 0; - $centreonesxd->create_vsphere_child(vsphere_name => $_, dynamic => 0); + foreach (keys %{$centreon_vmware->{centreon_vmware_config}->{vsphere_server}}) { + $centreon_vmware->{counter_stats}->{$_} = 0; + $centreon_vmware->create_vsphere_child(vsphere_name => $_, dynamic => 0); } - $centreonesxd->{logger}->writeLogInfo("[Server accepting clients]"); + $centreon_vmware->{logger}->writeLogInfo("[Server accepting clients]"); # Initialize poll set - $centreonesxd->{poll} = [ + $centreon_vmware->{poll} = [ { socket => $frontend, events => ZMQ_POLLIN, @@ -514,18 +531,18 @@ sub run { # Switch messages between sockets while (1) { - my $count = $centreonesxd->verify_child_vsphere(); + my $count = $centreon_vmware->verify_child_vsphere(); - if ($centreonesxd->{stop} == 1) { + if ($centreon_vmware->{stop} == 1) { # No childs if ($count == 0) { - $centreonesxd->{logger}->writeLogInfo("Quit main process"); + $centreon_vmware->{logger}->writeLogInfo("Quit main process"); zmq_close($frontend); exit(0); } } - zmq_poll($centreonesxd->{poll}, 5000); + zmq_poll($centreon_vmware->{poll}, 5000); } } diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm similarity index 83% rename from connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm rename to connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm index 46cf1e5e5..0f6b46418 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdalarmdatacenter; +package centreon::vmware::cmdalarmdatacenter; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); @@ -39,7 +56,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); @@ -81,7 +98,7 @@ sub run { } my @properties = ('name', 'triggeredAlarmState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -91,7 +108,7 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on datacenter(s)")); - my $alarmMgr = centreon::esxd::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); + my $alarmMgr = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $dc_alarms = {}; my $new_datas = {}; @@ -107,8 +124,8 @@ sub run { $new_datas->{$_->key} = 1; next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); - my $entity = centreon::esxd::common::get_view($self->{connector}, $_->entity, ['name']); - my $alarm = centreon::esxd::common::get_view($self->{connector}, $_->alarm, ['info']); + my $entity = centreon::vmware::common::get_view($self->{connector}, $_->entity, ['name']); + my $alarm = centreon::vmware::common::get_view($self->{connector}, $_->alarm, ['info']); $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, time => $_->time, name => $alarm->info->name, diff --git a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm similarity index 83% rename from connectors/vmware/src/centreon/esxd/cmdalarmhost.pm rename to connectors/vmware/src/centreon/vmware/cmdalarmhost.pm index 72bf58837..e3ecdbb31 100644 --- a/connectors/vmware/src/centreon/esxd/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdalarmhost; +package centreon::vmware::cmdalarmhost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); @@ -39,7 +56,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); @@ -81,7 +98,7 @@ sub run { } my @properties = ('name', 'triggeredAlarmState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -90,7 +107,7 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on host(s)")); - my $alarmMgr = centreon::esxd::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); + my $alarmMgr = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $host_alarms = {}; my $new_datas = {}; @@ -106,8 +123,8 @@ sub run { $new_datas->{$_->key} = 1; next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); - my $entity = centreon::esxd::common::get_view($self->{connector}, $_->entity, ['name']); - my $alarm = centreon::esxd::common::get_view($self->{connector}, $_->alarm, ['info']); + my $entity = centreon::vmware::common::get_view($self->{connector}, $_->entity, ['name']); + my $alarm = centreon::vmware::common::get_view($self->{connector}, $_->alarm, ['info']); $host_alarms->{$host_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, time => $_->time, name => $alarm->info->name, diff --git a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm similarity index 82% rename from connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm rename to connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm index 3a79ebfd4..5b0402eb6 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdcountvmhost; +package centreon::vmware::cmdcountvmhost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -50,7 +67,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -76,14 +93,14 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'vm', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - #return if (centreon::esxd::common::host_state($self->{connector}, $self->{lhost}, + #return if (centreon::vmware::common::host_state($self->{connector}, $self->{lhost}, # $$result[0]->{'runtime.connectionState'}->val) == 0); my @vm_array = (); @@ -93,7 +110,7 @@ sub run { } } @properties = ('runtime.powerState'); - my $result2 = centreon::esxd::common::get_views($self->{connector}, \@vm_array, \@properties); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); if ($multiple == 1) { @@ -102,7 +119,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm similarity index 79% rename from connectors/vmware/src/centreon/esxd/cmdcpuhost.pm rename to connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index c968593ac..d9a69fe79 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdcpuhost; +package centreon::vmware::cmdcpuhost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -53,7 +70,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); @@ -85,34 +102,34 @@ sub run { } my @properties = ('name', 'runtime.connectionState', 'summary.hardware.numCpuCores', 'summary.hardware.cpuMhz'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Total Average CPU usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); @@ -145,7 +162,7 @@ sub run { my ($counter_id, $instance) = split /:/, $id; if ($instance ne "") { $self->{manager}->{output}->perfdata_add(label => 'cpu' . $instance . $extra_label, unit => '%', - value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0]) * 0.01), + value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}[0]) * 0.01), min => 0, max => 100); } } diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm similarity index 80% rename from connectors/vmware/src/centreon/esxd/cmdcpuvm.pm rename to connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 753d75367..c9ae45354 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdcpuvm; +package centreon::vmware::cmdcpuvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -56,7 +73,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning_usagemhz', 'critical_usagemhz', 'warning_usage', 'critical_usage', 'warning_ready', 'critical_ready')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -95,18 +112,18 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, {'label' => 'cpu.ready.summation', 'instances' => \@instances}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -116,7 +133,7 @@ sub run { short_msg => sprintf("All cpu usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -124,9 +141,9 @@ sub run { powerstatus => $self->{nopoweredon_status}, multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); - my $total_cpu_ready = centreon::esxd::common::simplify_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{connector}->{perfcounter_speriod} * 1000) * 100); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_ready = centreon::vmware::common::simplify_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{connector}->{perfcounter_speriod} * 1000) * 100); my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits; @@ -160,7 +177,7 @@ sub run { my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; } $self->{manager}->{output}->output_add(long_msg => "$prefix_msg $long_msg"); @@ -183,7 +200,7 @@ sub run { next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); if ($instance ne "") { $self->{manager}->{output}->perfdata_add(label => 'cpu_' . $instance . '_MHz' . $extra_label, unit => 'MHz', - value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0])), + value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}[0])), min => 0); } } diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm similarity index 82% rename from connectors/vmware/src/centreon/esxd/cmddatastorehost.pm rename to connectors/vmware/src/centreon/vmware/cmddatastorehost.pm index 51db52214..a1520573f 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm @@ -1,10 +1,27 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmddatastorehost; +package centreon::vmware::cmddatastorehost; use strict; use warnings; use File::Basename; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -56,7 +73,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning', 'critical')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -88,7 +105,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'config.fileSystemVolume.mountInfo', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -108,7 +125,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -153,17 +170,17 @@ sub run { # Vsphere >= 4.1 # You get counters even if datastore is disconnect... - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, undef, $query_perfs, $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Datastore latencies are ok")); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; my $checked = {}; @@ -172,8 +189,8 @@ sub run { next if (defined($checked->{$uuid})); $checked->{$uuid} = 1; - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid}[0])); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid}[0])); + my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid}[0])); + my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid}[0])); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read on '%s' is %s ms", diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm similarity index 78% rename from connectors/vmware/src/centreon/esxd/cmddatastoreio.pm rename to connectors/vmware/src/centreon/vmware/cmddatastoreio.pm index 5ea1a4e25..1a9c6d00f 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmddatastoreio; +package centreon::vmware::cmddatastoreio; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -50,7 +67,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning', 'critical')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -82,16 +99,16 @@ sub run { $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary.name', 'summary.accessible'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -102,7 +119,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, + next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'}, status => $self->{disconnect_status}, @@ -110,8 +127,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # in KBps - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; + my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; + my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm similarity index 85% rename from connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm rename to connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 098f8cbb8..06942941a 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmddatastoreiops; +package centreon::vmware::cmddatastoreiops; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -50,7 +67,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning', 'critical')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -82,7 +99,7 @@ sub run { $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -98,7 +115,7 @@ sub run { my %datastore_lun = (); my $ds_checked = 0; foreach (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, + next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, name => $_->{'summary.name'}, state => $_->{'summary.accessible'}, status => $self->{disconnect_status}, @@ -139,14 +156,14 @@ sub run { } @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); - my $result2 = centreon::esxd::common::get_views($self->{connector}, \@vm_array, \@properties); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); # Remove disconnected or not running vm my %ref_ids_vm = (); for(my $i = $#{$result2}; $i >= 0; --$i) { - if (!centreon::esxd::common::is_connected(state => ${$result2}[$i]->{'runtime.connectionState'}->val) || - !centreon::esxd::common::is_running(power => ${$result2}[$i]->{'runtime.powerState'}->val)) { + if (!centreon::vmware::common::is_connected(state => ${$result2}[$i]->{'runtime.connectionState'}->val) || + !centreon::vmware::common::is_running(power => ${$result2}[$i]->{'runtime.powerState'}->val)) { splice @$result2, $i, 1; next; } @@ -154,14 +171,14 @@ sub run { } # Vsphere >= 4.1 - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result2, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); foreach (keys %$values) { my ($vm_id, $id, $disk_name) = split(/:/); @@ -169,7 +186,7 @@ sub run { # RDM Disk. We skip. Don't know how to manage it right now. next if (!defined($disk_name{$disk_name})); - my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{connector}->{perfcounter_speriod})); + my $tmp_value = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$_}[0] / $self->{connector}->{perfcounter_speriod})); $datastore_lun{$disk_name{$disk_name}}{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; if (!defined($datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}})) { $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}} = $tmp_value; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm similarity index 82% rename from connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm rename to connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm index 57f731b96..cc704846b 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmddatastoresnapshot; +package centreon::vmware::cmddatastoresnapshot; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -50,7 +67,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning_total', 'critical_total', 'warning_snapshot', 'critical_snapshot')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -76,7 +93,7 @@ sub run { $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary.accessible', 'summary.name', 'browser'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -86,7 +103,7 @@ sub run { my @ds_array = (); my %ds_names = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, + next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'}, status => $self->{disconnect_status}, @@ -99,7 +116,7 @@ sub run { @properties = (); my $result2; - return if (!($result2 = centreon::esxd::common::get_views($self->{connector}, \@ds_array, \@properties))); + return if (!($result2 = centreon::vmware::common::get_views($self->{connector}, \@ds_array, \@properties))); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All snapshot sizes are ok")); @@ -110,7 +127,7 @@ sub run { $dsName = $ds_names{$tmp_name}; $self->{manager}->{output}->output_add(long_msg => "Checking datastore '$dsName':"); - my ($snapshots, $msg) = centreon::esxd::common::search_in_datastore($self->{connector}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); + my ($snapshots, $msg) = centreon::vmware::common::search_in_datastore($self->{connector}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); if (!defined($snapshots)) { $msg =~ s/\n/ /g; if ($msg =~ /NoPermissionFault/i) { diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm similarity index 86% rename from connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm rename to connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index 1ea5b97f7..e4c66984a 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmddatastoreusage; +package centreon::vmware::cmddatastoreusage; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -54,7 +71,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning', 'critical')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -81,7 +98,7 @@ sub run { } my @properties = ('summary'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -93,7 +110,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::datastore_state(connector => $self->{connector}, + next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, name => $entity_view->summary->name, state => $entity_view->summary->accessible, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm similarity index 82% rename from connectors/vmware/src/centreon/esxd/cmddatastorevm.pm rename to connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 959581ad6..093e27ae1 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmddatastorevm; +package centreon::vmware::cmddatastorevm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; use File::Basename; sub new { @@ -62,7 +79,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning', 'critical')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -101,7 +118,7 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -119,7 +136,7 @@ sub run { my $mapped_datastore = {}; my @ds_array = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -137,7 +154,7 @@ sub run { } @properties = ('info'); - my $result2 = centreon::esxd::common::get_views($self->{connector}, \@ds_array, \@properties); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@ds_array, \@properties); return if (!defined($result2)); #my %uuid_list = (); @@ -158,25 +175,25 @@ sub run { # Vsphere >= 4.1 # We don't filter. To filter we'll need to get disk from vms - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Datastore IOPS counters are ok")); my $finded = 0; foreach my $entity_view (@$result) { - next if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0 && - centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0 && + centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; } $finded |= 1; @@ -195,8 +212,8 @@ sub run { foreach (sort keys %datastore_lun) { $finded |= 2; - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{connector}->{perfcounter_speriod})); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{connector}->{perfcounter_speriod})); + my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{connector}->{perfcounter_speriod})); + my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{connector}->{perfcounter_speriod})); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("%s read iops on '%s' is %s", diff --git a/connectors/vmware/src/centreon/esxd/cmdgetmap.pm b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm similarity index 68% rename from connectors/vmware/src/centreon/esxd/cmdgetmap.pm rename to connectors/vmware/src/centreon/vmware/cmdgetmap.pm index c5f761e1a..cab07b6ce 100644 --- a/connectors/vmware/src/centreon/esxd/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdgetmap; +package centreon::vmware::cmdgetmap; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -37,7 +54,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -60,7 +77,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'vm'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); $self->{manager}->{output}->output_add(severity => 'OK', @@ -77,7 +94,7 @@ sub run { } @properties = ('name', 'summary.runtime.powerState'); - my $result2 = centreon::esxd::common::get_views($self->{connector}, \@vm_array, \@properties); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); my %vms = (); diff --git a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm similarity index 87% rename from connectors/vmware/src/centreon/esxd/cmdhealthhost.pm rename to connectors/vmware/src/centreon/vmware/cmdhealthhost.pm index 2e1eee4ba..870ebd91c 100644 --- a/connectors/vmware/src/centreon/esxd/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdhealthhost; +package centreon::vmware::cmdhealthhost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -43,7 +60,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); @@ -71,7 +88,7 @@ sub run { my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -83,7 +100,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm similarity index 84% rename from connectors/vmware/src/centreon/esxd/cmdlimitvm.pm rename to connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index 82d6e6244..823fbdfff 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdlimitvm; +package centreon::vmware::cmdlimitvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -61,7 +78,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -78,7 +95,7 @@ sub display_verbose { foreach my $vm (sort keys %{$options{vms}}) { my $prefix = $vm; if ($options{vms}->{$vm} ne '') { - $prefix .= ' [' . centreon::esxd::common::strip_cr(value => $options{vms}->{$vm}) . ']'; + $prefix .= ' [' . centreon::vmware::common::strip_cr(value => $options{vms}->{$vm}) . ']'; } $self->{manager}->{output}->output_add(long_msg => ' ' . $prefix); } @@ -108,7 +125,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -126,7 +143,7 @@ sub run { my %memory_limit = (); my %disk_limit = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -134,7 +151,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); # CPU Limit if (defined($entity_view->{'config.cpuAllocation.limit'}) && $entity_view->{'config.cpuAllocation.limit'} != -1) { diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm similarity index 70% rename from connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm rename to connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm index 43726de1e..577b8d742 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistdatacenters.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdlistdatacenters; +package centreon::vmware::cmdlistdatacenters; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -37,7 +54,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -62,7 +79,7 @@ sub run { } my @properties = ('name'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); return if (!defined($result)); if (!defined($self->{disco_show})) { diff --git a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm similarity index 73% rename from connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm rename to connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm index 5c9c2983d..1575372e6 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistdatastores.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdlistdatastores; +package centreon::vmware::cmdlistdatastores; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -37,7 +54,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -62,7 +79,7 @@ sub run { } my @properties = ('summary'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); return if (!defined($result)); if (!defined($self->{disco_show})) { diff --git a/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm similarity index 77% rename from connectors/vmware/src/centreon/esxd/cmdlistnichost.pm rename to connectors/vmware/src/centreon/vmware/cmdlistnichost.pm index 78d9fc18d..c9c46c69c 100644 --- a/connectors/vmware/src/centreon/esxd/cmdlistnichost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdlistnichost; +package centreon::vmware::cmdlistnichost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -37,7 +54,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -53,7 +70,7 @@ sub run { my %filters = (name => $self->{esx_hostname}); my @properties = ('config.network.pnic', 'config.network.vswitch', 'config.network.proxySwitch'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); # Get Name from vswitch diff --git a/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm similarity index 78% rename from connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm rename to connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm index 5aef5eecc..987fa8adb 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmaintenancehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdmaintenancehost; +package centreon::vmware::cmdmaintenancehost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -49,7 +66,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -74,7 +91,7 @@ sub run { } my @properties = ('name', 'runtime.inMaintenanceMode', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -86,7 +103,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm similarity index 80% rename from connectors/vmware/src/centreon/esxd/cmdmemhost.pm rename to connectors/vmware/src/centreon/vmware/cmdmemhost.pm index f44fc447b..be06c740d 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdmemhost; +package centreon::vmware::cmdmemhost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -53,7 +70,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); @@ -84,26 +101,26 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'summary.hardware.memorySize', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All memory usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -112,8 +129,8 @@ sub run { my $memory_size = $entity_view->{'summary.hardware.memorySize'}; # in B # in KB - my $mem_used = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_used = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; my $prct_free = 100 - $prct_used; diff --git a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm similarity index 78% rename from connectors/vmware/src/centreon/esxd/cmdmemvm.pm rename to connectors/vmware/src/centreon/vmware/cmdmemvm.pm index f65367b08..edebe78ac 100644 --- a/connectors/vmware/src/centreon/esxd/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdmemvm; +package centreon::vmware::cmdmemvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -59,7 +76,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); @@ -97,10 +114,10 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{label => 'mem.active.average', instancess => ['']}, {label => 'mem.overhead.average', instances => ['']}, @@ -109,7 +126,7 @@ sub run { {label => 'mem.shared.average', instances => ['']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -119,7 +136,7 @@ sub run { short_msg => sprintf("All memory usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -130,11 +147,11 @@ sub run { my $memory_size = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; # in KB - my $mem_consumed = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_active = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_overhead = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_ballooning = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_shared = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_consumed = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_active = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_ballooning = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_shared = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])) * 1024; my $mem_free = $memory_size - $mem_consumed; my $prct_used = $mem_consumed * 100 / $memory_size; @@ -148,7 +165,7 @@ sub run { my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; } $self->{manager}->{output}->output_add(long_msg => sprintf("%s Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", diff --git a/connectors/vmware/src/centreon/esxd/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm similarity index 87% rename from connectors/vmware/src/centreon/esxd/cmdnethost.pm rename to connectors/vmware/src/centreon/vmware/cmdnethost.pm index 3cf5c1293..a754603eb 100644 --- a/connectors/vmware/src/centreon/esxd/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdnethost; +package centreon::vmware::cmdnethost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -62,7 +79,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -97,7 +114,7 @@ sub run { if (!defined($self->{no_proxyswitch})) { push @properties, 'config.network.proxySwitch'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -112,7 +129,7 @@ sub run { my $pnic_def_down = {}; my $query_perfs = []; foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -188,12 +205,12 @@ sub run { # Nothing to retrieve. problem before already. return if (scalar(@$query_perfs) == 0); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, undef, $query_perfs, $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; @@ -208,8 +225,8 @@ sub run { my @exits; foreach (sort keys %{$pnic_def_up->{$entity_value}}) { # KBps - my $traffic_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_}[0])) * 1024 * 8; - my $traffic_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $traffic_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $traffic_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_}[0])) * 1024 * 8; my $interface_speed = $pnic_def_up->{$entity_value}->{$_} * 1024 * 1024; my $in_prct = $traffic_in * 100 / $interface_speed; my $out_prct = $traffic_out * 100 / $interface_speed; diff --git a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm similarity index 84% rename from connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm rename to connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm index 3a6d028fd..ec855e091 100644 --- a/connectors/vmware/src/centreon/esxd/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdsnapshotvm; +package centreon::vmware::cmdsnapshotvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -50,7 +67,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning', 'critical')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); @@ -93,7 +110,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); my %vm_consolidate = (); @@ -109,7 +126,7 @@ sub run { short_msg => sprintf("Snapshot(s) OK")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -117,7 +134,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); if (defined($self->{check_consolidation}) && defined($entity_view->{'runtime.consolidationNeeded'}) && $entity_view->{'runtime.consolidationNeeded'} =~ /^true|1$/i) { $vm_consolidate{$entity_view->{name}} = 1; @@ -141,7 +158,7 @@ sub run { my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; } if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $vm_errors{$exit}->{$entity_view->{name}} = 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm similarity index 75% rename from connectors/vmware/src/centreon/esxd/cmdstatushost.pm rename to connectors/vmware/src/centreon/vmware/cmdstatushost.pm index 0ba24b655..034c28f74 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdstatushost; +package centreon::vmware::cmdstatushost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -43,7 +60,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -67,7 +84,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -92,7 +109,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm similarity index 77% rename from connectors/vmware/src/centreon/esxd/cmdstatusvm.pm rename to connectors/vmware/src/centreon/vmware/cmdstatusvm.pm index 43ab81f18..d4e389022 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdstatusvm; +package centreon::vmware::cmdstatusvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -43,7 +60,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -73,7 +90,7 @@ sub run { if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -98,7 +115,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm similarity index 79% rename from connectors/vmware/src/centreon/esxd/cmdswaphost.pm rename to connectors/vmware/src/centreon/vmware/cmdswaphost.pm index 1ab65443e..8dd4e58e6 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdswaphost; +package centreon::vmware::cmdswaphost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -53,7 +70,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); @@ -84,26 +101,26 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All swap rate usages are ok")); } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -111,8 +128,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm similarity index 80% rename from connectors/vmware/src/centreon/esxd/cmdswapvm.pm rename to connectors/vmware/src/centreon/vmware/cmdswapvm.pm index 14f2a8cd5..457ad4604 100644 --- a/connectors/vmware/src/centreon/esxd/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdswapvm; +package centreon::vmware::cmdswapvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -59,7 +76,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); @@ -98,16 +115,16 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{label => 'mem.swapinRate.average', instances => ['']}, {label => 'mem.swapoutRate.average', instances => ['']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if (scalar(@$result) > 1) { $multiple = 1; @@ -118,7 +135,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, power => $entity_view->{'runtime.powerState'}->val, @@ -128,8 +145,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); @@ -140,7 +157,7 @@ sub run { my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::esxd::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; } $self->{manager}->{output}->output_add(long_msg => sprintf("%s Swap In: %s Swap Out: %s", diff --git a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm similarity index 79% rename from connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm rename to connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index 81c89d4c2..974cb1e45 100644 --- a/connectors/vmware/src/centreon/esxd/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdthinprovisioningvm; +package centreon::vmware::cmdthinprovisioningvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -50,7 +67,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -66,7 +83,7 @@ sub display_verbose { foreach my $vm (sort keys %{$options{vms}}) { my $prefix = $vm; if ($options{vms}->{$vm}->{description} ne '') { - $prefix .= ' [' . centreon::esxd::common::strip_cr(value => $options{vms}->{$vm}->{description}) . ']'; + $prefix .= ' [' . centreon::vmware::common::strip_cr(value => $options{vms}->{$vm}->{description}) . ']'; } $self->{manager}->{output}->output_add(long_msg => $prefix); foreach my $disk (sort keys %{$options{vms}->{$vm}->{disks}}) { @@ -96,7 +113,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -120,7 +137,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -128,7 +145,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); foreach (@{$entity_view->{'config.hardware.device'}}) { if ($_->isa('VirtualDisk')) { diff --git a/connectors/vmware/src/centreon/esxd/cmdtimehost.pm b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm similarity index 70% rename from connectors/vmware/src/centreon/esxd/cmdtimehost.pm rename to connectors/vmware/src/centreon/vmware/cmdtimehost.pm index 99acc10d2..3ae1adfc9 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdtimehost; +package centreon::vmware::cmdtimehost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -37,7 +54,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -68,14 +85,14 @@ sub run { } my @properties = ('name', 'configManager.dateTimeSystem', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); $self->{manager}->{output}->output_add(severity => 'OK', short_msg => 'Time Host(s):'); my @host_array = (); foreach my $entity_view (@$result) { - if (centreon::esxd::common::is_connected(state => $entity_view->{'runtime.connectionState'}->{val}) == 0) { + if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->{val}) == 0) { $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s' is disconnected", $entity_view->{name})); next; @@ -86,7 +103,7 @@ sub run { } @properties = (); - my $result2 = centreon::esxd::common::get_views($self->{connector}, \@host_array, \@properties); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@host_array, \@properties); return if (!defined($result2)); foreach my $entity_view (@$result) { diff --git a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm similarity index 85% rename from connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm rename to connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index 45dc72316..60d4026d7 100644 --- a/connectors/vmware/src/centreon/esxd/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdtoolsvm; +package centreon::vmware::cmdtoolsvm; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -61,7 +78,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } @@ -78,7 +95,7 @@ sub display_verbose { foreach my $vm (sort keys %{$options{vms}}) { my $prefix = $vm; if ($options{vms}->{$vm} ne '') { - $prefix .= ' [' . centreon::esxd::common::strip_cr(value => $options{vms}->{$vm}) . ']'; + $prefix .= ' [' . centreon::vmware::common::strip_cr(value => $options{vms}->{$vm}) . ']'; } $self->{manager}->{output}->output_add(long_msg => ' ' . $prefix); } @@ -105,7 +122,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -122,7 +139,7 @@ sub run { my %not_running = (); my %not_up2date = (); foreach my $entity_view (@$result) { - next if (centreon::esxd::common::vm_state(connector => $self->{connector}, + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, @@ -130,7 +147,7 @@ sub run { multiple => $multiple) == 0); next if (defined($self->{nopoweredon_skip}) && - centreon::esxd::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); my $tools_status = lc($entity_view->{'summary.guest.toolsStatus'}->val); if ($tools_status eq 'toolsnotinstalled') { diff --git a/connectors/vmware/src/centreon/esxd/cmduptimehost.pm b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm similarity index 83% rename from connectors/vmware/src/centreon/esxd/cmduptimehost.pm rename to connectors/vmware/src/centreon/vmware/cmduptimehost.pm index 1267eeca0..25b5b974e 100644 --- a/connectors/vmware/src/centreon/esxd/cmduptimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmduptimehost; +package centreon::vmware::cmduptimehost; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; sub new { my $class = shift; @@ -53,7 +70,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); @@ -84,7 +101,7 @@ sub run { $filters{name} = qr/$self->{esx_hostname}/; } my @properties = ('name', 'runtime.bootTime', 'runtime.connectionState'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -96,7 +113,7 @@ sub run { } foreach my $entity_view (@$result) { - next if (centreon::esxd::common::host_state(connector => $self->{connector}, + next if (centreon::vmware::common::host_state(connector => $self->{connector}, hostname => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, status => $self->{disconnect_status}, diff --git a/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm similarity index 84% rename from connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm rename to connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm index 6810a6131..6ef2d9589 100644 --- a/connectors/vmware/src/centreon/esxd/cmdvmoperationcluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm @@ -1,9 +1,26 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::cmdvmoperationcluster; +package centreon::vmware::cmdvmoperationcluster; use strict; use warnings; -use centreon::esxd::common; +use centreon::vmware::common; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); @@ -47,7 +64,7 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; foreach my $label (('warning_svmotion', 'critical_svmotion', 'warning_vmotion', 'critical_vmotion', 'warning_clone', 'critical_clone')) { @@ -87,20 +104,20 @@ sub run { $filters{name} = qr/$self->{cluster}/; } my @properties = ('name'); - my $result = centreon::esxd::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => \%filters); return if (!defined($result)); if (scalar(@$result) > 1) { $multiple = 1; } - my $values = centreon::esxd::common::generic_performance_values_historic($self->{connector}, + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'vmop.numVMotion.latest', 'instances' => ['']}, {'label' => 'vmop.numSVMotion.latest', 'instances' => ['']}, {'label' => 'vmop.numClone.latest', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); - return if (centreon::esxd::common::performance_errors($self->{connector}, $values) == 1); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', @@ -112,7 +129,7 @@ sub run { my $checked = 0; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - my $name = centreon::esxd::common::substitute_name(value => $entity_view->{name}); + my $name = centreon::vmware::common::substitute_name(value => $entity_view->{name}); my %values = (); my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/vmware/common.pm similarity index 88% rename from connectors/vmware/src/centreon/esxd/common.pm rename to connectors/vmware/src/centreon/vmware/common.pm index d106c5d66..e51297319 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -1,5 +1,22 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::common; +package centreon::vmware::common; use warnings; use strict; @@ -51,10 +68,10 @@ sub response { } sub vmware_error { - my ($obj_esxd, $lerror) = @_; + my ($obj_vmware, $lerror) = @_; $manager_display->{output}->output_add(long_msg => $lerror); - $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $lerror"); + $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $lerror"); if ($lerror =~ /NoPermissionFault/i) { $manager_display->{output}->output_add(severity => 'UNKNOWN', short_msg => 'VMWare error: not enought permissions'); @@ -134,35 +151,35 @@ sub convert_number { } sub get_views { - my $obj_esxd = shift; + my $obj_vmware = shift; my $results; eval { - $results = $obj_esxd->{session1}->get_views(mo_ref_array => $_[0], properties => $_[1]); + $results = $obj_vmware->{session1}->get_views(mo_ref_array => $_[0], properties => $_[1]); }; if ($@) { - vmware_error($obj_esxd, $@); + vmware_error($obj_vmware, $@); return undef; } return $results; } sub get_view { - my $obj_esxd = shift; + my $obj_vmware = shift; my $results; eval { - $results = $obj_esxd->{session1}->get_view(mo_ref => $_[0], properties => $_[1]); + $results = $obj_vmware->{session1}->get_view(mo_ref => $_[0], properties => $_[1]); }; if ($@) { - vmware_error($obj_esxd, $@); + vmware_error($obj_vmware, $@); return undef; } return $results; } sub search_in_datastore { - my $obj_esxd = shift; + my $obj_vmware = shift; my ($ds_browse, $ds_name, $query, $return) = @_; my $result; @@ -179,26 +196,26 @@ sub search_in_datastore { }; if ($@) { return (undef, $@) if (defined($return) && $return == 1); - vmware_error($obj_esxd, $@); + vmware_error($obj_vmware, $@); return undef; } return $result; } sub get_perf_metric_ids { - my $obj_esxd = shift; + my $obj_vmware = shift; my $perf_names = $_[0]; my $filtered_list = []; foreach (@$perf_names) { - if (defined($obj_esxd->{perfcounter_cache}->{$_->{label}})) { + if (defined($obj_vmware->{perfcounter_cache}->{$_->{label}})) { foreach my $instance (@{$_->{instances}}) { - my $metric = PerfMetricId->new(counterId => $obj_esxd->{perfcounter_cache}->{$_->{label}}{key}, + my $metric = PerfMetricId->new(counterId => $obj_vmware->{perfcounter_cache}->{$_->{label}}{key}, instance => $instance); push @$filtered_list, $metric; } } else { - $obj_esxd->{logger}->writeLogError("Metric '" . $_->{label} . "' unavailable."); + $obj_vmware->{logger}->writeLogError("Metric '" . $_->{label} . "' unavailable."); $manager_display->{output}->output_add(severity => 'UNKNOWN', short_msg => "Counter doesn't exist. VMware version can be too old."); return undef; @@ -285,7 +302,7 @@ sub performance_builder_global { } sub generic_performance_values_historic { - my ($obj_esxd, $views, $perfs, $interval, %options) = @_; + my ($obj_vmware, $views, $perfs, $interval, %options) = @_; my $counter = 0; my %results; @@ -293,12 +310,12 @@ sub generic_performance_values_historic { my $perfdata; if (defined($views)) { - $perfdata = performance_builder_global(connector => $obj_esxd, + $perfdata = performance_builder_global(connector => $obj_vmware, views => $views, metrics => $perfs, interval => $interval); } else { - $perfdata = performance_builder_specific(connector => $obj_esxd, + $perfdata = performance_builder_specific(connector => $obj_vmware, metrics => $perfs, interval => $interval); } @@ -334,38 +351,38 @@ sub generic_performance_values_historic { } }; if ($@) { - $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@"); + $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); return undef; } return \%results; } sub cache_perf_counters { - my $obj_esxd = shift; + my $obj_vmware = 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}) { + $obj_vmware->{perfmanager_view} = $obj_vmware->{session1}->get_view(mo_ref => $obj_vmware->{session1}->get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']); + foreach (@{$obj_vmware->{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; + $obj_vmware->{perfcounter_cache}->{$label} = {'key' => $_->key, 'unitkey' => $_->unitInfo->key}; + $obj_vmware->{perfcounter_cache_reverse}->{$_->key} = $label; } - my $historical_intervals = $obj_esxd->{perfmanager_view}->historicalInterval; + my $historical_intervals = $obj_vmware->{perfmanager_view}->historicalInterval; foreach (@$historical_intervals) { - if ($obj_esxd->{perfcounter_speriod} == -1 || $obj_esxd->{perfcounter_speriod} > $_->samplingPeriod) { - $obj_esxd->{perfcounter_speriod} = $_->samplingPeriod; + if ($obj_vmware->{perfcounter_speriod} == -1 || $obj_vmware->{perfcounter_speriod} > $_->samplingPeriod) { + $obj_vmware->{perfcounter_speriod} = $_->samplingPeriod; } } # Put refresh = 20 (for ESX check) - if ($obj_esxd->{perfcounter_speriod} == -1) { - $obj_esxd->{perfcounter_speriod} = 20; + if ($obj_vmware->{perfcounter_speriod} == -1) { + $obj_vmware->{perfcounter_speriod} = 20; } }; if ($@) { - $obj_esxd->{logger}->writeLogError("'" . $obj_esxd->{whoaim} . "' $@"); + $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); return 1; } return 0; @@ -469,7 +486,7 @@ sub find_entity_views { } sub performance_errors { - my ($obj_esxd, $values) = @_; + my ($obj_vmware, $values) = @_; # Error counter not available or other from function return 1 if (!defined($values) || scalar(keys(%$values)) <= 0); diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm similarity index 81% rename from connectors/vmware/src/centreon/esxd/connector.pm rename to connectors/vmware/src/centreon/vmware/connector.pm index d5c2a4a86..6679c4f26 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -1,5 +1,22 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -package centreon::esxd::connector; +package centreon::vmware::connector; use strict; use VMware::VIRuntime; @@ -10,7 +27,7 @@ use ZMQ::Constants qw(:all); use File::Basename; use POSIX ":sys_wait_h"; use centreon::script; -use centreon::esxd::common; +use centreon::vmware::common; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my ($connector, $backend); @@ -108,11 +125,11 @@ sub handle_CHLD { sub response_router { my ($self, %options) = @_; - my $manager = centreon::esxd::common::init_response(); + my $manager = centreon::vmware::common::init_response(); $manager->{output}->output_add(severity => $options{severity}, short_msg => $options{msg}); $manager->{output}->{plugin} = $options{identity}; - centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend); + centreon::vmware::common::response(token => 'RESPSERVER2', endpoint => $backend); } sub verify_child { @@ -168,7 +185,7 @@ sub reqclient { $self->{modules_registry}->{$result->{command}}->initArgs(arguments => $result); $self->{modules_registry}->{$result->{command}}->run(); - centreon::esxd::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc:///tmp/centreonesxd/routing.ipc'); + centreon::vmware::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc:///tmp/centreon_vmware/routing.ipc'); zmq_close($backend); exit(0); } @@ -202,8 +219,8 @@ sub run { $backend = zmq_socket($context, ZMQ_DEALER); zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); zmq_setsockopt($backend, ZMQ_LINGER, 0); # we discard - zmq_connect($backend, 'ipc:///tmp/centreonesxd/routing.ipc'); - centreon::esxd::common::response(token => 'READY', endpoint => $backend, stdout => ''); + zmq_connect($backend, 'ipc:///tmp/centreon_vmware/routing.ipc'); + centreon::vmware::common::response(token => 'READY', endpoint => $backend, stdout => ''); # Initialize poll set my @poll = ( @@ -251,16 +268,16 @@ sub run { } if ($connector->{vsphere_connected} == 0) { - if (!centreon::esxd::common::connect_vsphere($connector->{logger}, - $connector->{whoaim}, - $connector->{config_vsphere_connect_timeout}, - \$connector->{session1}, - $connector->{config_vsphere_url}, - $connector->{config_vsphere_user}, - $connector->{config_vsphere_pass})) { + if (!centreon::vmware::common::connect_vsphere($connector->{logger}, + $connector->{whoaim}, + $connector->{config_vsphere_connect_timeout}, + \$connector->{session1}, + $connector->{config_vsphere_url}, + $connector->{config_vsphere_user}, + $connector->{config_vsphere_pass})) { $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Vsphere connection ok"); $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Create perf counters cache in progress"); - if (!centreon::esxd::common::cache_perf_counters($connector)) { + if (!centreon::vmware::common::cache_perf_counters($connector)) { $connector->{last_time_vsphere} = time(); $connector->{keeper_session_time} = time(); $connector->{vsphere_connected} = 1; @@ -274,7 +291,7 @@ sub run { ### if (defined($connector->{keeper_session_time}) && (time() - $connector->{keeper_session_time}) > ($connector->{config_vsphere_session_heartbeat} * 60)) { - centreon::esxd::common::heartbeat(connector => $connector); + centreon::vmware::common::heartbeat(connector => $connector); } my $data_element; diff --git a/connectors/vmware/src/centreon_vmware.pl b/connectors/vmware/src/centreon_vmware.pl new file mode 100644 index 000000000..050fd2fd1 --- /dev/null +++ b/connectors/vmware/src/centreon_vmware.pl @@ -0,0 +1,56 @@ +#!/usr/bin/perl +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use warnings; +use FindBin; +use lib "$FindBin::Bin"; +use centreon::script::centreon_vmware; + +centreon::script::centreon_vmware->new()->run(); + +__END__ + +=head1 NAME + +centreon_vmware.pl - a daemon to handle VMWare checks. + +=head1 SYNOPSIS + +centreon_vmware.pl [options] + +=head1 OPTIONS + +=over 8 + +=item B<--config-extra> + +Specify the path to the centreon_vmware configuration file (default: /etc/centreon/centreon_vmware.pm). + +=item B<--help> + +Print a brief help message and exits. + +=back + +=head1 DESCRIPTION + +B will connect to ESX and/or VirtualCenter. +Use the plugin 'apps::vmware::connector::plugin' from: https://github.com/centreon/centreon-plugins + +=cut From c1c1deeee36b498cc22af444d5eb4ea978e6980a Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 20 Jul 2015 13:45:44 +0200 Subject: [PATCH 133/447] + apache license --- connectors/vmware/LICENSE.txt | 201 ++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 connectors/vmware/LICENSE.txt diff --git a/connectors/vmware/LICENSE.txt b/connectors/vmware/LICENSE.txt new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/connectors/vmware/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From fe9398e88df9e27381ad2abefc112a855051c010 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 20 Jul 2015 14:57:18 +0200 Subject: [PATCH 134/447] + Add readme.md --- connectors/vmware/README.md | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 connectors/vmware/README.md diff --git a/connectors/vmware/README.md b/connectors/vmware/README.md new file mode 100644 index 000000000..17287955f --- /dev/null +++ b/connectors/vmware/README.md @@ -0,0 +1,69 @@ +# centreon-vmware + +“centreon-vmware” is a free and open source project. The project can be used with Centreon and all monitoring softwares compatible with Nagios plugins. +It's a Perl daemon in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare. + +The connector could get following indicators: +* For ESX Server: + * Current alarms + * CPU usage + * Memory usage + * Swap usage + * Interface trafics + * Count VMs + * Health status + * Global status + * Uptime +* For Virtual Machines: + * CPU usage + * Memory usage + * Swap usage + * IOPs on datastores + * Limits configured (CPU, memory and disks) + * Snapshot age and consolidation + * Thinprovisioning configuration + * VMTools state +* For Datastores: + * Usage + * IOPs + * Usage in bytes/s + * Snapshost sizes +* For Cluster: + * Operations on virtual machines (Clone, VMotion,...) +* For Datacenter: + * Current alarms + +You can check one or X entities for each checks. Moreover, you can also "scope" it. It means: i can check the virtual machines of a datacenter(s) and/or a cluster(s). + +Please follow the documentation for the installation: https://github.com/centreon/centreon-vmware/tree/master/docs/en/installation/index.rst + +## Examples + +Check vmtools states of virtual machines (with name matching the regexp 'prd'): + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=tools-vm --display-description --vm-hostname='prd' --filter + WARNING: 1 VM with VMTools not installed | + vmtools not installed: + prd-Reporting - 10.0.0.1 [description xxxx] + +Check datastore IOPs of virtual machines (with name matching the regexp 'centreon-central-1|Formation'): + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=datastore-vm --vm-hostname='centreon-central-1|Formation' --filter + OK: All Datastore IOPS counters are ok | 'riops_Formation-Reporting - 10.30.2.89_R&D-BI'=0.00iops;;;0; 'wiops_Formation-Reporting - 10.30.2.89_R&D-BI'=1.43iops;;;0; 'riops_centreon-central-1_INTEGRATION'=0.00iops;;;0; 'wiops_centreon-central-1_INTEGRATION'=0.60iops;;;0; + 'Formation-Reporting - 10.30.2.89' read iops on 'R&D-BI' is 0.00 + 'Formation-Reporting - 10.30.2.89' write iops on 'R&D-BI' is 1.43 + 'centreon-central-1' read iops on 'INTEGRATION' is 0.00 + 'centreon-central-1' write iops on 'INTEGRATION' is 0.60 + +Check the health of ESX Servers: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=health-host --esx-hostname='.*' --filter --disconnect-status='ok' + OK: All ESX health checks are ok | 'problems_srvi-clus-esx-n2.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n1.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n4.merethis.net'=0;;;0;186 'problems_srvi-clus-esx-n3.merethis.net'=0;;;0;186 + Checking srvi-clus-esx-n2.merethis.net + 299 health checks are green + Checking srvi-clus-esx-n1.merethis.net + 299 health checks are green + Checking srvi-clus-esx-n4.merethis.net + 186 health checks are green + Checking srvi-clus-esx-n3.merethis.net + 186 health checks are green From 90481a4edf7b33a80305ebd9b7943be487072f17 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 20 Jul 2015 16:27:50 +0200 Subject: [PATCH 135/447] + Update documentation --- .../vmware/doc/en/exploitation/index.rst | 46 ++++++++++++++++++- .../vmware/doc/fr/exploitation/index.rst | 43 +++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/doc/en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst index 9e06a9324..6f0b04794 100644 --- a/connectors/vmware/doc/en/exploitation/index.rst +++ b/connectors/vmware/doc/en/exploitation/index.rst @@ -65,6 +65,42 @@ In case you have many VirtualCenters, the configuration is (note the use of "," } ); +'other' and 'default' are containers name. + +Client Usage +------------ + +Check vmtools states of virtual machines (with name matching the regexp 'prd'): +:: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=tools-vm --display-description --vm-hostname='prd' --filter + WARNING: 1 VM with VMTools not installed | + vmtools not installed: + prd-Reporting - 10.0.0.1 [description xxxx] + +Check datastore IOPs of virtual machines (with name matching the regexp 'centreon-central-1|Formation'): +:: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=datastore-vm --vm-hostname='centreon-central-1|Formation' --filter + OK: All Datastore IOPS counters are ok | 'riops_Formation-Reporting - 10.30.2.89_R&D-BI'=0.00iops;;;0; 'wiops_Formation-Reporting - 10.30.2.89_R&D-BI'=1.43iops;;;0; 'riops_centreon-central-1_INTEGRATION'=0.00iops;;;0; 'wiops_centreon-central-1_INTEGRATION'=0.60iops;;;0; + 'Formation-Reporting - 10.30.2.89' read iops on 'R&D-BI' is 0.00 + 'Formation-Reporting - 10.30.2.89' write iops on 'R&D-BI' is 1.43 + 'centreon-central-1' read iops on 'INTEGRATION' is 0.00 + 'centreon-central-1' write iops on 'INTEGRATION' is 0.60 + +Check the health of ESX Servers: +:: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=health-host --esx-hostname='.*' --filter --disconnect-status='ok' + OK: All ESX health checks are ok | 'problems_srvi-clus-esx-n2.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n1.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n4.merethis.net'=0;;;0;186 'problems_srvi-clus-esx-n3.merethis.net'=0;;;0;186 + Checking srvi-clus-esx-n2.merethis.net + 299 health checks are green + Checking srvi-clus-esx-n1.merethis.net + 299 health checks are green + Checking srvi-clus-esx-n4.merethis.net + 186 health checks are green + Checking srvi-clus-esx-n3.merethis.net + 186 health checks are green Troubleshooting --------------- @@ -74,4 +110,12 @@ It is possible to get this kind of errors in the « logs » of « centreon-vm ...SOAP request error - possibly a protocol issue: read failed: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac... -VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. The bug comes from OpenSSL. It should be fix in OpenSSL 1.0.1h (CVE-2010-5298). \ No newline at end of file +VMWare Perl SDK sometimes generates this error that does not alter the behaviour of the connector. The bug comes from OpenSSL. It should be fix in OpenSSL 1.0.1h (CVE-2010-5298). + +You can have the following error returns by the connector: +:: + + # perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin ... + Cannot get value for counters... + +Please check that your VirtualCenter and ESX time synchronization. Most of the time, the server with the connector and/or VirtualCenter/ESX are not well synchronized. \ No newline at end of file diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index faa0fa3a4..2953e8e10 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -66,6 +66,42 @@ Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter } ); +'other' et 'default' sont des containeurs. + +Client Usage +------------ + +Vérifie l'état des VMTools des machines virtuelles avec 'prd' dans leur nom: +:: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=tools-vm --display-description --vm-hostname='prd' --filter + WARNING: 1 VM with VMTools not installed | + vmtools not installed: + prd-Reporting - 10.0.0.1 [description xxxx] + +Vérifie les IOPs des machines virtuelles (avec 'centreon-central-1|Formation' dans leur nom. Cela est une expression régulière) sur leurs datastores: +:: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=datastore-vm --vm-hostname='centreon-central-1|Formation' --filter + OK: All Datastore IOPS counters are ok | 'riops_Formation-Reporting - 10.30.2.89_R&D-BI'=0.00iops;;;0; 'wiops_Formation-Reporting - 10.30.2.89_R&D-BI'=1.43iops;;;0; 'riops_centreon-central-1_INTEGRATION'=0.00iops;;;0; 'wiops_centreon-central-1_INTEGRATION'=0.60iops;;;0; + 'Formation-Reporting - 10.30.2.89' read iops on 'R&D-BI' is 0.00 + 'Formation-Reporting - 10.30.2.89' write iops on 'R&D-BI' is 1.43 + 'centreon-central-1' read iops on 'INTEGRATION' is 0.00 + 'centreon-central-1' write iops on 'INTEGRATION' is 0.60 + +Vérifie l'état de santé des serveurs ESX: +:: + + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=health-host --esx-hostname='.*' --filter --disconnect-status='ok' + OK: All ESX health checks are ok | 'problems_srvi-clus-esx-n2.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n1.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n4.merethis.net'=0;;;0;186 'problems_srvi-clus-esx-n3.merethis.net'=0;;;0;186 + Checking srvi-clus-esx-n2.merethis.net + 299 health checks are green + Checking srvi-clus-esx-n1.merethis.net + 299 health checks are green + Checking srvi-clus-esx-n4.merethis.net + 186 health checks are green + Checking srvi-clus-esx-n3.merethis.net + 186 health checks are green Troubleshooting --------------- @@ -77,3 +113,10 @@ Il est possible de retrouver des erreurs de ce type dans les « logs » de « Le SDK Perl VMWare génère cette erreur de temps en temps mais ne bloque pas le fonctionnement du connecteur. Le bug provient d'OpenSSL. Il devrait être fix dans la version 1.0.1h (CVE-2010-5298). +Le connecteur peut retourner l'erreur suivante: +:: + + # perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin ... + Cannot get value for counters... + +Vérifier la synchronisation du temps du VirtualCenter et de ses serveurs ESX. La plupart du temps, le serveur hébergeant le connecteur ou le VirtualCenter/ESX ne sont pas bien synchronisés. From 96889a3b1e0ba00a42f3216ff17b195c77e59e25 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 21 Jul 2015 11:13:23 +0200 Subject: [PATCH 136/447] + Add debian wheezy system --- .../vmware/doc/en/installation/index.rst | 128 ++++++++++++++++- .../vmware/doc/fr/installation/index.rst | 136 +++++++++++++++++- .../packaging/debian/centreon_vmware-default | 9 ++ .../packaging/debian/centreon_vmware-init | 105 ++++++++++++++ 4 files changed, 365 insertions(+), 13 deletions(-) create mode 100644 connectors/vmware/packaging/debian/centreon_vmware-default create mode 100644 connectors/vmware/packaging/debian/centreon_vmware-init diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 237e5bc5c..6a96e651e 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -35,6 +35,118 @@ Hardware prerequisites will depend of check numbers. Minimal used resources are * RAM : 512 Mo (May slightly increase with the number of checks). * CPU : same as poller server. +Centreon-vmware Installation - Debian Wheezy +============================================ + +SDK Perl VMWare Installation +```````````````````````````` + +The "centreon-vmware" connector uses SDK Perl VMWare for its operation. So we install it with VMWare recommandation (only tested with version below). + +========================== ===================== ====================== +Dependency Version Repository +========================== ===================== ====================== +libwww-perl 6.04 wheezy +libxml-libxml-perl 2.0001 wheezy +libclass-methodmaker-perl 2.18 wheezy +libcrypt-ssleay-perl 0.58 wheezy +libsoap-lite-perl 0.714 wheezy +libuuid-perl 0.02 wheezy +========================== ===================== ====================== + +Install following dependency: +:: + + # aptitude install make libxml-libxml-perl libwww-perl libclass-methodmaker-perl libcrypt-ssleay-perl libsoap-lite-perl libuuid-perl + +Download the Perl SDK VMWare and install it: +:: + + # tar zxf VMware-vSphere-Perl-SDK-6.0.0-2503617.x86_64.tar.gz && cd vmware-vsphere-cli-distrib + # perl Makefile.PL + # make && make install + +Requirements +````````````` + +Following prerequisites are mandatory for « centreon_vmware »: + +* « perl-centreon-base »: module since Centreon 2.5 +* « centreon-plugins-base »: the client and some dependencies +* « zeromq » and Perl binding + +Following prerequisites are optional for « centreon_vmware »: + +* « libtimedate-perl » + +centreon-vmware Installation with source +```````````````````````````````````````` + +Install the following package: +:: + + # aptitude install libtimedate-perl + +Add the following line in « /etc/apt/sources.list » file: +:: + + deb http://http.debian.net/debian wheezy-backports main + +Install « zeromq » dependency: +:: + + # aptitude install libzmq3-dev gcc + # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-LibZMQ3-1.19.tar.gz + # tar zxf ZMQ-LibZMQ3-1.19.tar.gz && cd ZMQ-LibZMQ3-1.19 + # perl Makefile.PL + # make && make install + # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-Constants-1.04.tar.gz + # tar zxf ZMQ-Constants-1.04.tar.gz && cd ZMQ-Constants-1.04 + # perl Makefile.PL + # make && make install + +Download « centreon-vmware » archive, then install: +:: + + # tar zxvf centreon-vmware-2.0.0.tar.gz + # cd centreon-vmware-2.0.0 + # cp centreon_vmware.pl /usr/bin/ + + # mkdir -p /etc/centreon + # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + # cp contrib/debian/centreon_vmware-init /etc/init.d/centreon_vmware + # cp contrib/debian/centreon_vmware-default /etc/default/centreon_vmware + # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl + + # mkdir -p /usr/share/perl5/centreon/vmware/ /usr/share/perl5/centreon/script/ + # cp centreon/vmware/* /usr/share/perl5/centreon/vmware/ + # cp centreon/script/centreon_vmware.pm /usr/share/perl5/centreon/script/ + +Configure "centreon-vmware" daemon to start at boot: +:: + + # update-rc.d centreon_vmware defaults + +Install « perl-centreon-base » dependency: +:: + + # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon + # cd centreon + # cp lib/perl/centreon/script.pm /usr/share/perl5/centreon/ + # cp -R lib/perl/centreon/common /usr/share/perl5/centreon/ + +Install the client and dependency: +:: + + # git clone http://git.centreon.com/centreon-plugins.git + # cd centreon-plugins + # cp -R centreon/plugins /usr/share/perl5/centreon/ + # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + # cp centreon_plugins.pl /usr/lib/nagios/plugins/ + Centreon-vmware Installation - centos/rhel 5 systems ==================================================== @@ -55,7 +167,8 @@ perl-UUID 0.04 ces standard perl-VMware-vSphere 5.1.0-780721.1 ces standard ======================= ===================== ====================== -Install following dependency:: +Install following dependency: +:: # yum install perl-VMware-vSphere @@ -88,7 +201,8 @@ Install the client: centreon-vmware Installation with source ```````````````````````````````````````` -Download « centreon-vmware » archive, then install :: +Download « centreon-vmware » archive, then install: +:: # tar zxvf centreon-vmware-2.0.0.tar.gz # cd centreon-vmware-2.0.0 @@ -100,7 +214,7 @@ Download « centreon-vmware » archive, then install :: # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl - # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ + # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ # cp centreon/vmware/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ # cp centreon/script/centreon_vmware.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ @@ -117,11 +231,12 @@ Install « perl-centreon-base » dependency: # cp lib/perl/centreon/script.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/ # cp -R lib/perl/centreon/common /usr/lib/perl5/vendor_perl/5.8.8/centreon/ -Install the client: +Install the client and dependency: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins + # cp -R centreon/plugins /usr/lib/perl5/vendor_perl/5.8.8/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ @@ -195,7 +310,7 @@ Download « centreon-vmware » archive, then install: # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl - # mkdir -p /usr/share/perl5/vendor_perl/centreon/vmware/ + # mkdir -p /usr/share/perl5/vendor_perl/centreon/vmware/ /usr/share/perl5/vendor_perl/centreon/script/ # cp centreon/vmware/* /usr/share/perl5/vendor_perl/centreon/vmware/ # cp centreon/script/centreon_vmware.pm /usr/share/perl5/vendor_perl/centreon/script/ @@ -212,11 +327,12 @@ Install « perl-centreon-base » dependency: # cp lib/perl/centreon/script.pm /usr/share/perl5/vendor_perl/centreon/ # cp -R lib/perl/centreon/common /usr/share/perl5/vendor_perl/centreon/ -Install the client: +Install the client and dependency: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins + # cp -R centreon/plugins /usr/share/perl5/vendor_perl/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index 38686807b..113559dfb 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -35,6 +35,118 @@ Le matériel nécessaire dépend du nombre de demandes de vérifications. Par d * mémoire vive : 512 Mo minimum (Peut sensiblement augmenter en fonction du nombre de contrôle). * CPU : même pré-requis que pour le serveur de collecte. +Centreon-vmware Installation - Debian Wheezy +============================================ + +Installation du SDK Perl VMWare +``````````````````````````````` + +Le connecteur « centreon-vmware » utilise le SDK Perl VMWare pour son fonctionnement. Nous allons donc l'installer en suivant les versions recommandées par VMWare (en dehors de ces versions, le fonctionnement n'est pas garanti). + +========================== ===================== ====================== +Dependency Version Repository +========================== ===================== ====================== +libwww-perl 6.04 wheezy +libxml-libxml-perl 2.0001 wheezy +libclass-methodmaker-perl 2.18 wheezy +libcrypt-ssleay-perl 0.58 wheezy +libsoap-lite-perl 0.714 wheezy +libuuid-perl 0.02 wheezy +========================== ===================== ====================== + +Installer les dépendances suivantes: +:: + + # aptitude install make libxml-libxml-perl libwww-perl libclass-methodmaker-perl libcrypt-ssleay-perl libsoap-lite-perl libuuid-perl + +Télécharger et installer le Perl SDK VMWare: +:: + + # tar zxf VMware-vSphere-Perl-SDK-6.0.0-2503617.x86_64.tar.gz && cd vmware-vsphere-cli-distrib + # perl Makefile.PL + # make && make install + +Pré-requis +`````````` + +Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_vmware »: + +* « perl-centreon-base »: module depuis Centreon 2.5 +* « centreon-plugins-base »: le client et des dépendances +* « zeromq » et son module Perl + +Les dépendances suivantes sont optionnelles pour le fonctionnement de « centreon_vmware »: + +* « libtimedate-perl » + +Installation de centreon-vmware par les sources +``````````````````````````````````````````````` + +Installer le paquet suivant: +:: + + # aptitude install libtimedate-perl + +Ajouter la ligne suivante dans le fichier « /etc/apt/sources.list »: +:: + + deb http://http.debian.net/debian wheezy-backports main + +Installer la dépendance « zeromq »: +:: + + # aptitude install libzmq3-dev gcc + # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-LibZMQ3-1.19.tar.gz + # tar zxf ZMQ-LibZMQ3-1.19.tar.gz && cd ZMQ-LibZMQ3-1.19 + # perl Makefile.PL + # make && make install + # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-Constants-1.04.tar.gz + # tar zxf ZMQ-Constants-1.04.tar.gz && cd ZMQ-Constants-1.04 + # perl Makefile.PL + # make && make install + +Télécharger l'archive de « centreon-vmware » et installer le connecteur: +:: + + # tar zxvf centreon-vmware-2.0.0.tar.gz + # cd centreon-vmware-2.0.0 + # cp centreon_vmware.pl /usr/bin/ + + # mkdir -p /etc/centreon + # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + # cp contrib/debian/centreon_vmware-init /etc/init.d/centreon_vmware + # cp contrib/debian/centreon_vmware-default /etc/default/centreon_vmware + # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl + + # mkdir -p /usr/share/perl5/centreon/vmware/ /usr/share/perl5/centreon/script/ + # cp centreon/vmware/* /usr/share/perl5/centreon/vmware/ + # cp centreon/script/centreon_vmware.pm /usr/share/perl5/centreon/script/ + +Activer le daemon « centreon-vmware » au démarrage: +:: + + # update-rc.d centreon_vmware defaults + +Installer la dépendance « perl-centreon-base »: +:: + + # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon + # cd centreon + # cp lib/perl/centreon/script.pm /usr/share/perl5/centreon/ + # cp -R lib/perl/centreon/common /usr/share/perl5/centreon/ + +Installer le client et les dépendances: +:: + + # git clone http://git.centreon.com/centreon-plugins.git + # cd centreon-plugins + # cp -R centreon/plugins /usr/share/perl5/centreon/ + # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ + # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ + # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ + # cp centreon_plugins.pl /usr/lib/nagios/plugins/ + Installation de centreon-vmware - Environnement centos/rhel 5 ============================================================= @@ -55,7 +167,8 @@ perl-UUID 0.04 ces standard perl-VMware-vSphere 5.1.0-780721.1 ces standard ======================= ===================== ====================== -Installer la dépendance suivante:: +Installer la dépendance suivante: +:: # yum install perl-VMware-vSphere @@ -90,7 +203,8 @@ Installation de centreon-vmware par les sources Télécharger l'archive de « centreon-vmware ». -Installer les fichiers:: +Installer les fichiers: +:: # tar zxvf centreon-vmware-2.0.0.tar.gz # cd centreon-vmware-2.0.0 @@ -102,11 +216,12 @@ Installer les fichiers:: # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl - # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ + # mkdir -p /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ # cp centreon/vmware/* /usr/lib/perl5/vendor_perl/5.8.8/centreon/vmware/ # cp centreon/script/centreon_vmware.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/script/ -Activer le daemon « centreon-vmware » au démarrage:: +Activer le daemon « centreon-vmware » au démarrage: +:: # chkconfig --level 2345 centreon_vmware on @@ -118,11 +233,12 @@ Installer la dépendance « perl-centreon-base »: # cp lib/perl/centreon/script.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/ # cp -R lib/perl/centreon/common /usr/lib/perl5/vendor_perl/5.8.8/centreon/ -Installer le client: +Installer le client et les dépendances: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins + # cp -R centreon/plugins /usr/lib/perl5/vendor_perl/5.8.8/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ @@ -198,10 +314,15 @@ Installer le connecteur: # cp contrib/redhat/centreon_vmware-sysconfig /etc/sysconfig/centreon_vmware # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl - # mkdir -p /usr/share/perl5/vendor_perl/centreon/vmware/ + # mkdir -p /usr/share/perl5/vendor_perl/centreon/vmware/ /usr/share/perl5/vendor_perl/centreon/script/ # cp centreon/vmware/* /usr/share/perl5/vendor_perl/centreon/vmware/ # cp centreon/script/centreon_vmware.pm /usr/share/perl5/vendor_perl/centreon/script/ +Activer le daemon « centreon-vmware » au démarrage: +:: + + # chkconfig --level 2345 centreon_vmware on + Installer la dépendance « perl-centreon-base »: :: @@ -210,11 +331,12 @@ Installer la dépendance « perl-centreon-base »: # cp lib/perl/centreon/script.pm /usr/share/perl5/vendor_perl/centreon/ # cp -R lib/perl/centreon/common /usr/share/perl5/vendor_perl/centreon/ -Installer le client: +Installer le client et les dépendances: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins + # cp -R centreon/plugins /usr/share/perl5/vendor_perl/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ diff --git a/connectors/vmware/packaging/debian/centreon_vmware-default b/connectors/vmware/packaging/debian/centreon_vmware-default new file mode 100644 index 000000000..a5aca771a --- /dev/null +++ b/connectors/vmware/packaging/debian/centreon_vmware-default @@ -0,0 +1,9 @@ +# Configuration for /etc/init.d/centreon_vmware + +# If run centcore at startup default: YES +RUN_AT_STARTUP="YES" + +# Centreon user default: root +CENTREON_USER="root" + +OPTIONS="--logfile=/var/log/centreon_vmware.log --severity=error" \ No newline at end of file diff --git a/connectors/vmware/packaging/debian/centreon_vmware-init b/connectors/vmware/packaging/debian/centreon_vmware-init new file mode 100644 index 000000000..7a44d6d80 --- /dev/null +++ b/connectors/vmware/packaging/debian/centreon_vmware-init @@ -0,0 +1,105 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: centreon_vmware.pl +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Should-Start: +# Should-Stop: +# Short-Description: Start daemon centreon_vmware.pl at boot +# Description: +### END INIT INFO + +PKGNAME=centreon_vmware +DESC="centreon-vmware" +DAEMON=/usr/bin/centreon_vmware.pl +PIDFILE=/var/run/centreon/centreon_vmware.pid +FOLDER=/var/run/centreon/ +if [ ! -d "$FOLDER" ]; then # Control will enter here if $DIRECTORY doesn't exist. + mkdir $FOLDER +fi + +if [ ! -x "${DAEMON}" ]; then + echo "The program ${DAEMON} does not exists or is not executable" + exit 3 +fi + +# Include the default user configuration if exists +[ -r /etc/default/${PKGNAME} ] && . /etc/default/${PKGNAME} + +# Load the VERBOSE setting and other rcS variables +[ -f /etc/init/vars.sh ] && . /etc/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +if [ -z "${RUN_AT_STARTUP}" -o "${RUN_AT_STARTUP}" != "YES" ]; then + log_warning_msg "Not starting $PKGNAME, edit /etc/default/$PKGNAME to start it." + exit 0 +fi + +if [ -z "${CENTREON_USER}" ]; then + log_warning_msg "Not starting $PKGNAME, CENTREON_USER not set in /etc/default/$PKGNAME." + exit 0 +fi + +do_start() +{ + start-stop-daemon --start --background --quiet --pidfile ${PIDFILE} --exec ${DAEMON} \ + --chuid ${CENTREON_USER} --user ${CENTREON_USER} --test -- $OPTIONS + [ "$?" = "0" ] || return 1 + start-stop-daemon --start --background --quiet --pidfile ${PIDFILE} --exec ${DAEMON} \ + --make-pidfile --chuid ${CENTREON_USER} --user ${CENTREON_USER} -- $OPTIONS + [ "$?" = "0" ] || return 2 + return 0 +} + +do_stop() +{ + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user ${CENTREON_USER} --pidfile ${PIDFILE} + [ "$?" = "2" ] && return 2 + rm -rf ${PIDFILE} + [ "$?" = 0 ] && return 0 || return 1 +} + +case "$1" in + start) + [ "${VERBOSE}" != "no" ] && log_daemon_msg "Starting ${DESC}" "${PKGNAME}" + do_start + case "$?" in + 0|1) [ "${VERBOSE}" != "no" ] && log_end_msg 0 ;; + 2) [ "${VERBOSE}" != "no" ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "${VERBOSE}" != no ] && log_daemon_msg "Stopping ${DESC}" "${PKGNAME}" + do_stop + case "$?" in + 0|1) [ "${VERBOSE}" != no ] && log_end_msg 0 ;; + 2) [ "${VERBOSE}" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc ${DAEMON} ${PKGNAME} -p ${PIDFILE} + ;; + restart|force-reload) + [ "${VERBOSE}" != no ] && log_daemon_msg "Restarting ${DESC}" "${PKGNAME}" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; + *) log_end_msg 1 ;; + esac + ;; + *) log_end_msg 1 ;; + esac + ;; + *) + echo "Usage: ${SCRIPTNAME} (start|stop|status|restart|force-reload)" >&2 + exit 3 +esac \ No newline at end of file From 4b0cf4b10a1d7830c6d2dfaa22a6b46164b206f7 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 31 Jul 2015 11:23:47 +0200 Subject: [PATCH 137/447] + Fix port usage --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index c311f9dc0..6fd7180b3 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -510,7 +510,7 @@ sub run { } zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard - zmq_bind($frontend, 'tcp://*:5700'); + zmq_bind($frontend, 'tcp://*:' . $centreon_vmware->{centreon_vmware_config}->{port}); $centreon_vmware->bind_ipc(socket => $frontend, ipc_file => '/tmp/centreon_vmware/routing.ipc'); foreach (keys %{$centreon_vmware->{centreon_vmware_config}->{vsphere_server}}) { From b42f4f2a210ea1b4066fb3bdb8c655918a28445d Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 12 Aug 2015 11:07:59 +0200 Subject: [PATCH 138/447] + add provisioned value for 'datastorage-usage' mode + add 'datastore-countvm' --- .../src/centreon/script/centreon_vmware.pm | 1 + .../centreon/vmware/cmddatastorecountvm.pm | 166 ++++++++++++++++++ .../src/centreon/vmware/cmddatastoreusage.pm | 39 +++- 3 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 6fd7180b3..8132acea3 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -51,6 +51,7 @@ my @load_modules = ( 'centreon::vmware::cmdcountvmhost', 'centreon::vmware::cmdcpuhost', 'centreon::vmware::cmdcpuvm', + 'centreon::vmware::cmddatastorecountvm', 'centreon::vmware::cmddatastoreio', 'centreon::vmware::cmddatastoreiops', 'centreon::vmware::cmddatastorehost', diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm new file mode 100644 index 000000000..352a6e2d5 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm @@ -0,0 +1,166 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmddatastorecountvm; + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'datastorecountvm'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::vmware::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{connector} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datastore_name}/; + } + my @properties = ('summary.name', 'vm', 'summary.accessible'); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + + my @vm_array = (); + foreach my $entity_view (@$result) { + if (defined($entity_view->vm)) { + @vm_array = (@vm_array, @{$entity_view->vm}); + } + } + @properties = ('runtime.powerState'); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); + return if (!defined($result2)); + + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastores are ok")); + } + + foreach my $entity_view (@$result) { + next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, + name => $entity_view->{'summary.name'}, + state => $entity_view->{'summary.accessible'}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{'summary.name'} if ($multiple == 1); + my %vm_states = (poweredon => 0, poweredoff => 0, suspended => 0); + if (defined($entity_view->vm)) { + foreach my $vm_host (@{$entity_view->vm}) { + foreach my $vm (@{$result2}) { + if ($vm_host->{value} eq $vm->{mo_ref}->{value}) { + my $power_value = lc($vm->{'runtime.powerState'}->val); + $vm_states{$power_value}++; + last; + } + } + } + } + + foreach my $labels ((['poweredon', 'warning_on', 'critical_on'], + ['poweredoff', 'warning_off', 'critical_off'], + ['suspended', 'warning_suspended', 'critical_suspended'])) { + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $vm_states{$labels->[0]}, + threshold => [ { label => $labels->[2], exit_litteral => 'critical' }, + { label => $labels->[1], exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{'summary.name'}, + $vm_states{$labels->[0]}, + $labels->[0])); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{'summary.name'}, + $vm_states{$labels->[0]}, + $labels->[0])); + } + + $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, + value => $vm_states{$labels->[0]}, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), + min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index e4c66984a..5f80a9fd6 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -55,7 +55,7 @@ sub checkArgs { $self->{output}->add_option_msg(short_msg => "Wrong units option '" . (defined($options{arguments}->{units}) ? $options{arguments}->{units} : 'null') . "'."); $self->{output}->option_exit(); } - foreach my $label (('warning', 'critical')) { + foreach my $label (('warning', 'critical', 'warning_provisioned', 'critical_provisioned')) { if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); @@ -73,7 +73,7 @@ sub initArgs { } $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical')) { + foreach my $label (('warning', 'critical', 'warning_provisioned', 'critical_provisioned')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); } } @@ -126,6 +126,7 @@ sub run { } # in Bytes + my $exits = []; my $name_storage = $entity_view->summary->name; my $total_size = $entity_view->summary->capacity; my $total_free = $entity_view->summary->freeSpace; @@ -133,29 +134,42 @@ sub run { my $prct_used = $total_used * 100 / $total_size; my $prct_free = 100 - $prct_used; - my ($exit, $threshold_value); + my ($total_uncommited, $prct_uncommited); + my $msg_uncommited = ''; + if (defined($entity_view->summary->uncommitted)) { + $total_uncommited = $total_used + $entity_view->summary->uncommitted; + $prct_uncommited = $total_uncommited * 100 / $total_size; + my ($total_uncommited_value, $total_uncommited_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_uncommited); + $msg_uncommited = sprintf(" Provisioned: %s (%.2f%%)", $total_uncommited_value . " " . $total_uncommited_unit, $prct_uncommited); + push @{$exits}, $self->{manager}->{perfdata}->threshold_check(value => $prct_uncommited, threshold => [ { label => 'critical_provisioned', exit_litteral => 'critical' }, { label => 'warning_provisioned', exit_litteral => 'warning' } ]); + } + + my ($threshold_value); $threshold_value = $total_used; $threshold_value = $total_free if (defined($self->{free})); if ($self->{units} eq '%') { $threshold_value = $prct_used; $threshold_value = $prct_free if (defined($self->{free})); } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - + push @{$exits}, $self->{manager}->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{output}->get_most_critical(status => $exits); + my ($total_size_value, $total_size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_size); my ($total_used_value, $total_used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_used); my ($total_free_value, $total_free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_free); - $self->{manager}->{output}->output_add(long_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $self->{manager}->{output}->output_add(long_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)%s", $name_storage, $total_size_value . " " . $total_size_unit, $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free)); + $total_free_value . " " . $total_free_unit, $prct_free, + $msg_uncommited)); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + short_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)%s", $name_storage, $total_size_value . " " . $total_size_unit, $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free)); + $total_free_value . " " . $total_free_unit, $prct_free, + $msg_uncommited)); } my $label = 'used'; @@ -176,6 +190,13 @@ sub run { warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), min => 0, max => $total_size); + if (defined($total_uncommited)) { + $self->{manager}->{output}->perfdata_add(label => 'provisioned' . $extra_label, unit => 'B', + value => $total_uncommited, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_provisioned', total => $total_size, cast_int => 1), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_provisioned', total => $total_size, cast_int => 1), + min => 0, max => $total_size); + } } } From 7cc54836cd32dbcece822c8a6346d57dfa235494 Mon Sep 17 00:00:00 2001 From: Centreon Date: Mon, 31 Aug 2015 16:33:51 +0200 Subject: [PATCH 139/447] Initial commit --- connectors/vmware/LICENSE | 202 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 connectors/vmware/LICENSE diff --git a/connectors/vmware/LICENSE b/connectors/vmware/LICENSE new file mode 100644 index 000000000..8f71f43fe --- /dev/null +++ b/connectors/vmware/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + From 33c41ecd64f9d25ab039fb7a6c55086903f5d3fd Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 14 Sep 2015 12:21:25 +0200 Subject: [PATCH 140/447] + Fix link --- connectors/vmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/README.md b/connectors/vmware/README.md index 17287955f..8063633e7 100644 --- a/connectors/vmware/README.md +++ b/connectors/vmware/README.md @@ -35,7 +35,7 @@ The connector could get following indicators: You can check one or X entities for each checks. Moreover, you can also "scope" it. It means: i can check the virtual machines of a datacenter(s) and/or a cluster(s). -Please follow the documentation for the installation: https://github.com/centreon/centreon-vmware/tree/master/docs/en/installation/index.rst +Please follow the documentation for the installation: https://github.com/centreon/centreon-vmware/blob/master/doc/en/installation/index.rst ## Examples From 6d4993dd5fadb3458b351a3d0ae9ab6f3fefdb81 Mon Sep 17 00:00:00 2001 From: rwerquin Date: Fri, 25 Sep 2015 16:00:47 +0200 Subject: [PATCH 141/447] good project name in documentation --- connectors/vmware/doc/en/conf.py | 8 ++++---- connectors/vmware/doc/en/index.rst | 4 ++-- connectors/vmware/doc/fr/conf.py | 8 ++++---- connectors/vmware/doc/fr/index.rst | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/connectors/vmware/doc/en/conf.py b/connectors/vmware/doc/en/conf.py index e9144e890..016e8817d 100644 --- a/connectors/vmware/doc/en/conf.py +++ b/connectors/vmware/doc/en/conf.py @@ -40,17 +40,17 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Centreon ESXD' -copyright = u'2013, Merethis' +project = u'Centreon VMWare' +copyright = u'2015, Centreon' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.0' +version = '2.0' # The full version, including alpha/beta/rc tags. -release = '1.0.0' +release = '2.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/connectors/vmware/doc/en/index.rst b/connectors/vmware/doc/en/index.rst index 14a3134a6..cb63e74a4 100644 --- a/connectors/vmware/doc/en/index.rst +++ b/connectors/vmware/doc/en/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to Centreon ESXD's documentation! -========================================= +Welcome to Centreon VMWare's documentation! +=========================================== Contents: diff --git a/connectors/vmware/doc/fr/conf.py b/connectors/vmware/doc/fr/conf.py index e9144e890..016e8817d 100644 --- a/connectors/vmware/doc/fr/conf.py +++ b/connectors/vmware/doc/fr/conf.py @@ -40,17 +40,17 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Centreon ESXD' -copyright = u'2013, Merethis' +project = u'Centreon VMWare' +copyright = u'2015, Centreon' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.0' +version = '2.0' # The full version, including alpha/beta/rc tags. -release = '1.0.0' +release = '2.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/connectors/vmware/doc/fr/index.rst b/connectors/vmware/doc/fr/index.rst index 14a3134a6..cb63e74a4 100644 --- a/connectors/vmware/doc/fr/index.rst +++ b/connectors/vmware/doc/fr/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to Centreon ESXD's documentation! -========================================= +Welcome to Centreon VMWare's documentation! +=========================================== Contents: From 9d861f8baffea61ca7458c18d41eca0dd7e392a8 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 5 Oct 2015 16:52:24 +0200 Subject: [PATCH 142/447] + protect more functions --- .../vmware/src/centreon/script/centreon_vmware.pm | 14 +++++++++----- connectors/vmware/src/centreon/vmware/connector.pm | 4 ++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 8132acea3..5240a0c1c 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -458,15 +458,19 @@ sub create_vsphere_child { $self->{whoaim} = $options{vsphere_name}; $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{running} = 0; $self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{ready} = 0; - $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); + $self->{logger}->writeLogInfo("Create vsphere sub-process for '" . $options{vsphere_name} . "'"); my $child_vpshere_pid = fork(); + if (!defined($child_vpshere_pid)) { + $self->{logger}->writeLogError("Cannot fork for '" . $options{vsphere_name} . "': $!"); + return -1; + } if ($child_vpshere_pid == 0) { my $connector = centreon::vmware::connector->new(name => $self->{whoaim}, - modules_registry => $self->{modules_registry}, - module_date_parse_loaded => $self->{module_date_parse_loaded}, - config => $self->{centreon_vmware_config}, - logger => $self->{logger}); + modules_registry => $self->{modules_registry}, + module_date_parse_loaded => $self->{module_date_parse_loaded}, + config => $self->{centreon_vmware_config}, + logger => $self->{logger}); $connector->run(); exit(0); } diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 6679c4f26..6b57a40be 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -199,6 +199,10 @@ sub vsphere_event { while (1) { # Process all parts of the message my $message = zmq_recvmsg($backend); + if (!defined($message)) { + $connector->{logger}->writeLogError("zmq_recvmsg error: $!"); + last; + } my $data = zmq_msg_data($message); if ($data =~ /^REQCLIENT\s+(.*)$/msi) { From 34bc91ae33b1b98fb3b0dfc6f42ad2853e6a0022 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 5 Oct 2015 16:58:45 +0200 Subject: [PATCH 143/447] + add some debug message --- connectors/vmware/src/centreon/vmware/connector.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 6b57a40be..5ac753e4a 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -218,6 +218,7 @@ sub run { my ($connector) = shift; my $timeout_process = 0; + $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' init begin"); my $context = zmq_init(); $backend = zmq_socket($context, ZMQ_DEALER); @@ -235,6 +236,7 @@ sub run { }, ); + $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' init done"); while (1) { my $progress = $connector->verify_child(); From c39d908c1526f5b2316b6049771f58b485f32120 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 5 Oct 2015 17:13:19 +0200 Subject: [PATCH 144/447] + manage some unusual case (can happen...) --- .../src/centreon/script/centreon_vmware.pm | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 5240a0c1c..597116421 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -263,20 +263,23 @@ sub verify_child_vsphere { if (defined($self->{childs_vpshere_pid}->{$_})) { if ($self->{stop} == 0) { + my $name = $self->{childs_vpshere_pid}->{$_}; $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "'???!! we relaunch it!!!"); if ($self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{dynamic} == 0) { - $self->create_vsphere_child(vsphere_name => $self->{childs_vpshere_pid}->{$_}, dynamic => 0); + # Can have the same pid (so we delete before) + delete $self->{childs_vpshere_pid}->{$_}; + $self->create_vsphere_child(vsphere_name => $name, dynamic => 0); } else { $self->{logger}->writeLogError("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' is dead. But we don't relaunch it (dynamic sub-process)"); delete $self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}; + delete $self->{childs_vpshere_pid}->{$_}; } } else { $self->{logger}->writeLogInfo("Sub-process for '" . $self->{childs_vpshere_pid}->{$_} . "' dead ???!!"); $self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{running} = 0; + delete $self->{childs_vpshere_pid}->{$_}; } - - delete $self->{childs_vpshere_pid}->{$_}; } } @@ -300,6 +303,9 @@ sub waiting_ready { return 1 if ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 1); + # Need to check if we need to relaunch (maybe it can have a problem) + $self->check_childs(); + my $time = time(); # We wait 10 seconds while ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 0 && @@ -452,6 +458,20 @@ sub router_event { } } +sub check_childs { + my ($self, %options) = @_; + + my $count = $self->verify_child_vsphere(); + if ($self->{stop} == 1) { + # No childs + if ($count == 0) { + $self->{logger}->writeLogInfo("Quit main process"); + zmq_close($frontend); + exit(0); + } + } +} + sub create_vsphere_child { my ($self, %options) = @_; @@ -536,17 +556,7 @@ sub run { # Switch messages between sockets while (1) { - my $count = $centreon_vmware->verify_child_vsphere(); - - if ($centreon_vmware->{stop} == 1) { - # No childs - if ($count == 0) { - $centreon_vmware->{logger}->writeLogInfo("Quit main process"); - zmq_close($frontend); - exit(0); - } - } - + $centreon_vmware->check_childs(); zmq_poll($centreon_vmware->{poll}, 5000); } } From eaf8b91988b67992066acbb29982d87deb29f2bc Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 9 Oct 2015 10:51:07 +0200 Subject: [PATCH 145/447] + Fix output when no vm on the datastore --- .../vmware/src/centreon/vmware/cmddatastoreiops.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 06942941a..d88efd646 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -154,6 +154,12 @@ sub run { } } } + + if (scalar(@vm_array) == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => "No virtual machines on the datastore"); + return ; + } @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); @@ -169,6 +175,12 @@ sub run { } $ref_ids_vm{${$result2}[$i]->{mo_ref}->{value}} = ${$result2}[$i]->{name}; } + + if ($multiple == 0 && scalar(@{$result2}) == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => "No active virtual machines on the datastore"); + return ; + } # Vsphere >= 4.1 my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, From 32b6c8ddccc72e028877466671637c3d3f0bda8c Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 30 Oct 2015 10:38:35 +0100 Subject: [PATCH 146/447] + Fix #4 --- connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm | 1 - connectors/vmware/src/centreon/vmware/cmdalarmhost.pm | 1 - 2 files changed, 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm index 0f6b46418..ad51078c7 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm @@ -108,7 +108,6 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on datacenter(s)")); - my $alarmMgr = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $dc_alarms = {}; my $new_datas = {}; diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm index e3ecdbb31..af9b1983d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm @@ -107,7 +107,6 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("No current alarms on host(s)")); - my $alarmMgr = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->alarmManager, undef); my $total_alarms = { red => 0, yellow => 0 }; my $host_alarms = {}; my $new_datas = {}; From 474018f35947505f1b7765242ae19e0f4763064e Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 30 Oct 2015 13:48:02 +0100 Subject: [PATCH 147/447] + Fix #2 : add to getmap mode the esx version --- connectors/vmware/src/centreon/vmware/cmdgetmap.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm index cab07b6ce..3b98a61f2 100644 --- a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm @@ -76,7 +76,7 @@ sub run { } else { $filters{name} = qr/$self->{esx_hostname}/; } - my @properties = ('name', 'vm'); + my @properties = ('name', 'vm', 'config.product.version'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); @@ -84,7 +84,7 @@ sub run { short_msg => sprintf("List ESX host(s):")); foreach my $entity_view (@$result) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s%s", $entity_view->name, + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [v%s] %s", $entity_view->name, $entity_view->{'config.product.version'}, defined($self->{vm_no}) ? '' : ':')); next if (defined($self->{vm_no})); From 6ca6e16bd73150a32d990a1f263bfc55760df16a Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 30 Oct 2015 16:12:07 +0100 Subject: [PATCH 148/447] + Fix #6 --- connectors/vmware/src/centreon/vmware/cmdmemvm.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index edebe78ac..8f126b4ee 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -119,7 +119,7 @@ sub run { my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, - [{label => 'mem.active.average', instancess => ['']}, + [{label => 'mem.active.average', instances => ['']}, {label => 'mem.overhead.average', instances => ['']}, {label => 'mem.vmmemctl.average', instances => ['']}, {label => 'mem.consumed.average', instances => ['']}, From eb370da61aa959c8a52aaaae2c65826fff82fd42 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 30 Oct 2015 17:12:33 +0100 Subject: [PATCH 149/447] + Fix #1 Add option to handle timeshift and sampling period Also manage some errors on counters --- .../vmware/src/centreon/vmware/cmdcpuhost.pm | 15 +-- .../vmware/src/centreon/vmware/cmdcpuvm.pm | 18 +++- .../src/centreon/vmware/cmddatastorehost.pm | 5 +- .../src/centreon/vmware/cmddatastoreio.pm | 5 +- .../src/centreon/vmware/cmddatastoreiops.pm | 7 +- .../src/centreon/vmware/cmddatastorevm.pm | 15 ++- .../vmware/src/centreon/vmware/cmdmemhost.pm | 5 +- .../vmware/src/centreon/vmware/cmdmemvm.pm | 11 ++- .../vmware/src/centreon/vmware/cmdnethost.pm | 5 +- .../vmware/src/centreon/vmware/cmdswaphost.pm | 9 +- .../vmware/src/centreon/vmware/cmdswapvm.pm | 5 +- .../centreon/vmware/cmdvmoperationcluster.pm | 3 +- .../vmware/src/centreon/vmware/common.pm | 93 ++++++++++++++----- 13 files changed, 138 insertions(+), 58 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index d9a69fe79..36d760436 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -113,10 +113,13 @@ sub run { $result, [{'label' => 'cpu.usage.average', 'instances' => \@instances}, {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], - $self->{connector}->{perfcounter_speriod}, + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + my $interval_min = centreon::vmware::common::get_interval_min(speriod => $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}); if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Total Average CPU usages are ok")); @@ -128,19 +131,19 @@ sub run { status => $self->{disconnect_status}, multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"} * 0.01)); + my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"})); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", - $entity_view->{name}, $total_cpu_average, int($self->{connector}->{perfcounter_speriod} / 60))); + $entity_view->{name}, $total_cpu_average, $interval_min)); if ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, short_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", - $entity_view->{name}, $total_cpu_average, int($self->{connector}->{perfcounter_speriod} / 60))); + $entity_view->{name}, $total_cpu_average, $interval_min)); } my $extra_label = ''; @@ -162,7 +165,7 @@ sub run { my ($counter_id, $instance) = split /:/, $id; if ($instance ne "") { $self->{manager}->{output}->perfdata_add(label => 'cpu' . $instance . $extra_label, unit => '%', - value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}[0]) * 0.01), + value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}) * 0.01), min => 0, max => 100); } } diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index c9ae45354..21828e001 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -122,6 +122,7 @@ sub run { {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, {'label' => 'cpu.ready.summation', 'instances' => \@instances}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -132,6 +133,13 @@ sub run { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All cpu usages are ok")); } + + my $interval_sec = $self->{connector}->{perfcounter_speriod}; + if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { + $interval_sec = $self->{sampling_period}; + } + my $interval_min = centreon::vmware::common::get_interval_min(speriod => $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}); foreach my $entity_view (@$result) { next if (centreon::vmware::common::vm_state(connector => $self->{connector}, hostname => $entity_view->{name}, @@ -141,9 +149,9 @@ sub run { powerstatus => $self->{nopoweredon_status}, multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"}[0])); - my $total_cpu_ready = centreon::vmware::common::simplify_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"}[0] / ($self->{connector}->{perfcounter_speriod} * 1000) * 100); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"} * 0.01)); + my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"})); + my $total_cpu_ready = centreon::vmware::common::simplify_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"} / ($interval_sec * 1000) * 100); my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits; @@ -173,7 +181,7 @@ sub run { min => $entry->{perf_min}, max => $entry->{perf_max}); } - $long_msg .= ' on last ' . int($self->{connector}->{perfcounter_speriod} / 60) . ' min'; + $long_msg .= ' on last ' . $interval_min . ' min'; my $prefix_msg = "'$entity_view->{name}'"; if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && $entity_view->{'config.annotation'} ne '') { @@ -200,7 +208,7 @@ sub run { next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); if ($instance ne "") { $self->{manager}->{output}->perfdata_add(label => 'cpu_' . $instance . '_MHz' . $extra_label, unit => 'MHz', - value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}[0])), + value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id})), min => 0); } } diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm index a1520573f..11c298d50 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm @@ -174,6 +174,7 @@ sub run { undef, $query_perfs, $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -189,8 +190,8 @@ sub run { next if (defined($checked->{$uuid})); $checked->{$uuid} = 1; - my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid}[0])); - my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid}[0])); + my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid})); + my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid})); my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read on '%s' is %s ms", diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm index 1a9c6d00f..66108d125 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm @@ -107,6 +107,7 @@ sub run { [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -127,8 +128,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # in KBps - my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; - my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; + my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"})) * 1024; + my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"})) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index d88efd646..5839e28c0 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -188,17 +188,22 @@ sub run { [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + my $interval_sec = $self->{connector}->{perfcounter_speriod}; + if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { + $interval_sec = $self->{sampling_period}; + } foreach (keys %$values) { my ($vm_id, $id, $disk_name) = split(/:/); # RDM Disk. We skip. Don't know how to manage it right now. next if (!defined($disk_name{$disk_name})); - my $tmp_value = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$_}[0] / $self->{connector}->{perfcounter_speriod})); + my $tmp_value = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$_} / $interval_sec)); $datastore_lun{$disk_name{$disk_name}}{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; if (!defined($datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}})) { $datastore_lun{$disk_name{$disk_name}}{$vm_id . '_' . $self->{connector}->{perfcounter_cache_reverse}->{$id}} = $tmp_value; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 093e27ae1..280b03182 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -180,9 +180,14 @@ sub run { [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + my $interval_sec = $self->{connector}->{perfcounter_speriod}; + if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { + $interval_sec = $self->{sampling_period}; + } $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All Datastore IOPS counters are ok")); my $finded = 0; @@ -207,15 +212,15 @@ sub run { next if ($disk_name{$disk_name} !~ /$ds_regexp/); $datastore_lun{$disk_name{$disk_name}} = { 'disk.numberRead.summation' => 0, 'disk.numberWrite.summation' => 0 } if (!defined($datastore_lun{$disk_name{$disk_name}})); - $datastore_lun{$disk_name{$disk_name}}->{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}[0]; + $datastore_lun{$disk_name{$disk_name}}->{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}; } foreach (sort keys %datastore_lun) { $finded |= 2; - my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $self->{connector}->{perfcounter_speriod})); - my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $self->{connector}->{perfcounter_speriod})); + my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $interval_sec)); + my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $interval_sec)); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("%s read iops on '%s' is %s", $prefix_msg, $_, $read_counter)); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { @@ -223,7 +228,7 @@ sub run { short_msg => sprintf("%s read iops on '%s' is %s", $prefix_msg, $_, $read_counter)); } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("%s write iops on '%s' is %s", $prefix_msg, $_, $write_counter)); if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index be06c740d..77d7287c4 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -112,6 +112,7 @@ sub run { [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -129,8 +130,8 @@ sub run { my $memory_size = $entity_view->{'summary.hardware.memorySize'}; # in B # in KB - my $mem_used = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_used = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"})) * 1024; + my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"})) * 1024; my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; my $prct_free = 100 - $prct_used; diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index 8f126b4ee..9b4e952c9 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -125,6 +125,7 @@ sub run { {label => 'mem.consumed.average', instances => ['']}, {label => 'mem.shared.average', instances => ['']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -147,11 +148,11 @@ sub run { my $memory_size = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; # in KB - my $mem_consumed = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_active = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_ballooning = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"}[0])) * 1024; - my $mem_shared = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"}[0])) * 1024; + my $mem_consumed = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"})) * 1024; + my $mem_active = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"})) * 1024; + my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"})) * 1024; + my $mem_ballooning = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"})) * 1024; + my $mem_shared = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"})) * 1024; my $mem_free = $memory_size - $mem_consumed; my $prct_used = $mem_consumed * 100 / $memory_size; diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index a754603eb..e7407bad9 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -209,6 +209,7 @@ sub run { undef, $query_perfs, $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -225,8 +226,8 @@ sub run { my @exits; foreach (sort keys %{$pnic_def_up->{$entity_value}}) { # KBps - my $traffic_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_}[0])) * 1024 * 8; - my $traffic_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_}[0])) * 1024 * 8; + my $traffic_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_})) * 1024 * 8; + my $traffic_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_})) * 1024 * 8; my $interface_speed = $pnic_def_up->{$entity_value}->{$_} * 1024 * 1024; my $in_prct = $traffic_in * 100 / $interface_speed; my $out_prct = $traffic_out * 100 / $interface_speed; diff --git a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm index 8dd4e58e6..a2f627e26 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm @@ -112,6 +112,7 @@ sub run { [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, {'label' => 'mem.swapoutRate.average', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -128,11 +129,11 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"})) * 1024; + my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"})) * 1024; - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); diff --git a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm index 457ad4604..e75897ab0 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -123,6 +123,7 @@ sub run { [{label => 'mem.swapinRate.average', instances => ['']}, {label => 'mem.swapoutRate.average', instances => ['']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -145,8 +146,8 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; # KBps - my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"}[0])) * 1024; - my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"}[0])) * 1024; + my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"})) * 1024; + my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"})) * 1024; my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm index 6ef2d9589..822a926b3 100644 --- a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm @@ -116,6 +116,7 @@ sub run { {'label' => 'vmop.numSVMotion.latest', 'instances' => ['']}, {'label' => 'vmop.numClone.latest', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); @@ -135,7 +136,7 @@ sub run { my @exits; foreach my $label (('Clone', 'VMotion', 'SVMotion')) { - $new_datas->{$label . '_' . $entity_value} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.num' . $label . '.latest'}->{key} . ":"}[0]; + $new_datas->{$label . '_' . $entity_value} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.num' . $label . '.latest'}->{key} . ":"}; $old_datas->{$label . '_' . $entity_value} = $self->{statefile_cache}->get(name => $label . '_' . $entity_value); next if (!defined($old_datas->{$label . '_' . $entity_value})); diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index e51297319..4bee216ff 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -203,19 +203,26 @@ sub search_in_datastore { } sub get_perf_metric_ids { - my $obj_vmware = shift; - my $perf_names = $_[0]; + my (%options) = @_; my $filtered_list = []; - foreach (@$perf_names) { - if (defined($obj_vmware->{perfcounter_cache}->{$_->{label}})) { + foreach (@{$options{metrics}}) { + if (defined($options{connector}->{perfcounter_cache}->{$_->{label}})) { foreach my $instance (@{$_->{instances}}) { - my $metric = PerfMetricId->new(counterId => $obj_vmware->{perfcounter_cache}->{$_->{label}}{key}, - instance => $instance); + if ($options{connector}->{perfcounter_cache}->{$_->{label}}{level} > $options{connector}->{sampling_periods}->{$options{interval}}->{level}) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", + $_->{label}, $options{interval}, + $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, + $options{connector}->{sampling_periods}->{$options{interval}}->{level})); + return undef; + } + my $metric = PerfMetricId->new(counterId => $options{connector}->{perfcounter_cache}->{$_->{label}}{key}, + instance => $instance); push @$filtered_list, $metric; } } else { - $obj_vmware->{logger}->writeLogError("Metric '" . $_->{label} . "' unavailable."); + $options{connector}->{logger}->writeLogError("Metric '" . $_->{label} . "' unavailable."); $manager_display->{output}->output_add(severity => 'UNKNOWN', short_msg => "Counter doesn't exist. VMware version can be too old."); return undef; @@ -227,13 +234,16 @@ sub get_perf_metric_ids { sub performance_builder_specific { my (%options) = @_; + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; my @perf_query_spec; foreach my $entry (@{$options{metrics}}) { - my $perf_metric_ids = get_perf_metric_ids($options{connector}, $entry->{metrics}); + my $perf_metric_ids = get_perf_metric_ids(connector => $options{connector}, + metrics => $entry->{metrics}, + interval => $options{interval}); return undef if (!defined($perf_metric_ids)); my $tstamp = time(); - my (@t) = gmtime($tstamp - $options{interval}); + my (@t) = gmtime($tstamp - $options{interval} - $time_shift); 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); @@ -245,8 +255,9 @@ sub performance_builder_specific { format => 'normal', intervalId => 20, startTime => $startTime, - endTime => $endTime, - maxSample => 1); + endTime => $endTime + ); + #maxSample => 1); } else { push @perf_query_spec, PerfQuerySpec->new(entity => $entry->{entity}, metricId => $perf_metric_ids, @@ -265,12 +276,15 @@ sub performance_builder_specific { sub performance_builder_global { my (%options) = @_; + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; my @perf_query_spec; - my $perf_metric_ids = get_perf_metric_ids($options{connector}, $options{metrics}); + my $perf_metric_ids = get_perf_metric_ids(connector => $options{connector}, + metrics => $options{metrics}, + interval => $options{interval}); return undef if (!defined($perf_metric_ids)); my $tstamp = time(); - my (@t) = gmtime($tstamp - $options{interval}); + my (@t) = gmtime($tstamp - $options{interval} - $time_shift); 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); @@ -284,8 +298,8 @@ sub performance_builder_global { format => 'normal', intervalId => 20, startTime => $startTime, - endTime => $endTime, - maxSample => 1); + endTime => $endTime); + #maxSample => 1); } else { push @perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $perf_metric_ids, @@ -306,6 +320,21 @@ sub generic_performance_values_historic { my $counter = 0; my %results; + # overload the default sampling choosen + if (defined($options{sampling_period}) && $options{sampling_period} ne '') { + $interval = $options{sampling_period}; + } + # check sampling period exist + if (!defined($obj_vmware->{sampling_periods}->{$interval})) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Sampling period '%s' not managed.", $interval)); + return undef; + } + if ($obj_vmware->{sampling_periods}->{$interval}->{enabled} != 1) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Sampling period '%s' collection data no enabled.", $interval)); + return undef; + } eval { my $perfdata; @@ -313,11 +342,11 @@ sub generic_performance_values_historic { $perfdata = performance_builder_global(connector => $obj_vmware, views => $views, metrics => $perfs, - interval => $interval); + interval => $interval, time_shift => $options{time_shift}); } else { $perfdata = performance_builder_specific(connector => $obj_vmware, metrics => $perfs, - interval => $interval); + interval => $interval, time_shift => $options{time_shift}); } return undef if (!defined($perfdata)); @@ -337,15 +366,23 @@ sub generic_performance_values_historic { return undef; } + my $aggregated_counter_value = 0; + foreach my $counter_value (@{$_->value}) { + $aggregated_counter_value += $counter_value; + } + if (scalar(@{$_->value}) > 1) { + $aggregated_counter_value /= scalar(@{$_->value}); + } + if (defined($options{multiples}) && $options{multiples} == 1) { if (defined($options{multiples_result_by_entity}) && $options{multiples_result_by_entity} == 1) { $results{$val->{entity}->{value}} = {} if (!defined($results{$val->{entity}->{value}})); - $results{$val->{entity}->{value}}->{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + $results{$val->{entity}->{value}}->{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $aggregated_counter_value; } else { - $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $aggregated_counter_value; } } else { - $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $aggregated_counter_value; } } } @@ -364,16 +401,18 @@ sub cache_perf_counters { $obj_vmware->{perfmanager_view} = $obj_vmware->{session1}->get_view(mo_ref => $obj_vmware->{session1}->get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']); foreach (@{$obj_vmware->{perfmanager_view}->perfCounter}) { my $label = $_->groupInfo->key . "." . $_->nameInfo->key . "." . $_->rollupType->val; - $obj_vmware->{perfcounter_cache}->{$label} = {'key' => $_->key, 'unitkey' => $_->unitInfo->key}; + $obj_vmware->{perfcounter_cache}->{$label} = { key => $_->key, unitkey => $_->unitInfo->key, level => $_->level }; $obj_vmware->{perfcounter_cache_reverse}->{$_->key} = $label; } my $historical_intervals = $obj_vmware->{perfmanager_view}->historicalInterval; + $obj_vmware->{sampling_periods} = {}; foreach (@$historical_intervals) { if ($obj_vmware->{perfcounter_speriod} == -1 || $obj_vmware->{perfcounter_speriod} > $_->samplingPeriod) { $obj_vmware->{perfcounter_speriod} = $_->samplingPeriod; } + $obj_vmware->{sampling_periods}->{$_->samplingPeriod} = $_; } # Put refresh = 20 (for ESX check) @@ -493,6 +532,18 @@ sub performance_errors { return 0; } +sub get_interval_min { + my (%options) = @_; + + my $interval = $options{speriod}; + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; + if (defined($options{sampling_period}) && $options{sampling_period} ne '') { + $interval = $options{sampling_period}; + } + + return int(($interval + $time_shift) / 60); +} + sub is_accessible { my (%options) = @_; From 2751b93a5f526ba2d38e1cf0ea1946d7e2160126 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 2 Dec 2015 11:29:35 +0100 Subject: [PATCH 150/447] + Fix #3 --- .../src/centreon/script/centreon_vmware.pm | 1 + .../src/centreon/vmware/cmdservicehost.pm | 152 ++++++++++++++++++ .../src/centreon/vmware/cmdstatushost.pm | 8 +- .../vmware/src/centreon/vmware/common.pm | 15 ++ 4 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 connectors/vmware/src/centreon/vmware/cmdservicehost.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 597116421..a7cecba4d 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -68,6 +68,7 @@ my @load_modules = ( 'centreon::vmware::cmdmaintenancehost', 'centreon::vmware::cmdmemvm', 'centreon::vmware::cmdnethost', + 'centreon::vmware::cmdservicehost', 'centreon::vmware::cmdsnapshotvm', 'centreon::vmware::cmdstatushost', 'centreon::vmware::cmdstatusvm', diff --git a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm new file mode 100644 index 000000000..f2ed9d966 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm @@ -0,0 +1,152 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdservicehost; + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my $class = shift; + my $self = {}; + $self->{logger} = shift; + $self->{commandName} = 'servicehost'; + + bless $self, $class; + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::vmware::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{connector} = $options{connector}; +} + +sub run { + my $self = shift; + + my %filters = (); + my $multiple = 0; + + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'runtime.connectionState', 'runtime.inMaintenanceMode', 'configManager.serviceSystem'); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + return if (!defined($result)); + + my %host_names = (); + my @host_array = (); + foreach my $entity_view (@$result) { + next if (centreon::vmware::common::host_state(connector => $self->{connector}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + next if (centreon::vmware::common::host_maintenance(connector => $self->{connector}, + hostname => $entity_view->{name}, + maintenance => $entity_view->{'runtime.inMaintenanceMode'}, + multiple => $multiple) == 0); + if (defined($entity_view->{'configManager.serviceSystem'})) { + push @host_array, $entity_view->{'configManager.serviceSystem'}; + $host_names{$entity_view->{'configManager.serviceSystem'}->{value}} = $entity_view->{name}; + } + } + + return if (scalar(@host_array) == 0); + + @properties = ('serviceInfo'); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@host_array, \@properties); + return if (!defined($result2)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All ESX services are ok")); + } + + foreach my $entity (@$result2) { + my $hostname = $host_names{$entity->{mo_ref}->{value}}; + + my @services_ok = (); + my @services_problem = (); + foreach my $service (@{$entity->{serviceInfo}->{service}}) { + next if (defined($self->{filter_services}) && $self->{filter_services} ne '' && + $service->{key} !~ /$self->{filter_services}/); + + if ($service->{policy} =~ /^on|automatic/i && !$service->{running}) { + push @services_problem, $service->{key}; + } else { + push @services_ok, $service->{key}; + } + } + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' services [ ok : %s ] [ nok : %s ]", $hostname, + join(', ', @services_ok), join(', ', @services_problem))); + my $status = 'OK'; + $status = 'CRITICAL' if (scalar(@services_problem) > 0); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $status, + short_msg => sprintf("'%s' services [ ok : %s ] [ nok : %s ]", $hostname, + join(', ', @services_ok), join(', ', @services_problem))); + } + } +} + +1; diff --git a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm index 034c28f74..46b146e29 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm @@ -110,10 +110,10 @@ sub run { foreach my $entity_view (@$result) { next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); my $status_esx = $entity_view->{'summary.overallStatus'}->val; $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 4bee216ff..148d8a161 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -633,6 +633,21 @@ sub host_state { return 1; } +sub host_maintenance { + my (%options) = @_; + + if ($options{maintenance} =~ /^true|1$/) { + my $output = "Host '" . $options{hostname} . "' is in maintenance mode."; + if ($options{multiple} == 0) { + $manager_display->{output}->output_add(severity => 'OK', + short_msg => $output); + } + return 0; + } + + return 1; +} + sub substitute_name { my (%options) = @_; From 4eac315b8d447e8690e27b146256e95061f9e077 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 2 Dec 2015 11:41:59 +0100 Subject: [PATCH 151/447] + add changelog --- connectors/vmware/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 connectors/vmware/changelog diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog new file mode 100644 index 000000000..42ed661af --- /dev/null +++ b/connectors/vmware/changelog @@ -0,0 +1,10 @@ +2015-12-02 Quentin Garnier - 2.1.0 + * Enhance: Add a command to monitor ESX services (issue #3) + * Enhance: Can choose the sampling period (issue #1) + * Enhance: Display ESX version in command 'getmap' (issue #2) + * Fix: Hardening connector (issue #5) + * Fix: error for 'alarm-*' commands (issue #4) + * Fix: counter 'active' for command 'memory-vm' (issue #6) + +2015-09-23 Quentin Garnier - 2.0.0 + * initial release \ No newline at end of file From 323e843460b76c92bba3241f54aaede701721230 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 3 Dec 2015 11:12:32 +0100 Subject: [PATCH 152/447] + update changelog + Ref #1 --- connectors/vmware/changelog | 2 +- connectors/vmware/src/centreon/vmware/common.pm | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 42ed661af..b890c5301 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,4 +1,4 @@ -2015-12-02 Quentin Garnier - 2.1.0 +2015-12-03 Quentin Garnier - 2.1.0 * Enhance: Add a command to monitor ESX services (issue #3) * Enhance: Can choose the sampling period (issue #1) * Enhance: Display ESX version in command 'getmap' (issue #2) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 148d8a161..73507a0d4 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -324,13 +324,13 @@ sub generic_performance_values_historic { if (defined($options{sampling_period}) && $options{sampling_period} ne '') { $interval = $options{sampling_period}; } - # check sampling period exist - if (!defined($obj_vmware->{sampling_periods}->{$interval})) { + # check sampling period exist (period 20 is not listed) + if ($interval != 20 && !defined($obj_vmware->{sampling_periods}->{$interval})) { $manager_display->{output}->output_add(severity => 'UNKNOWN', short_msg => sprintf("Sampling period '%s' not managed.", $interval)); return undef; } - if ($obj_vmware->{sampling_periods}->{$interval}->{enabled} != 1) { + if ($interval != 20 && $obj_vmware->{sampling_periods}->{$interval}->{enabled} != 1) { $manager_display->{output}->output_add(severity => 'UNKNOWN', short_msg => sprintf("Sampling period '%s' collection data no enabled.", $interval)); return undef; From 4d076a4bb0f8154ff66eb6b3090839fdf7163689 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 4 Jan 2016 15:37:21 +0100 Subject: [PATCH 153/447] + Better way to manage the two ssl backend for lwp --- .../vmware/src/centreon/script/centreon_vmware.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index a7cecba4d..c9bed5e5f 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -36,7 +36,19 @@ use centreon::vmware::connector; my ($centreon_vmware, $frontend); BEGIN { + # In new version version of LWP (version 6), the backend is now 'IO::Socket::SSL' (instead Crypt::SSLeay) + # it's a hack if you unset that + #$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL"; + + # The option is not omit to verify the certificate chain. $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; + + eval { + # required for new IO::Socket::SSL versions + require IO::Socket::SSL; + IO::Socket::SSL->import(); + IO::Socket::SSL::set_ctx_defaults( SSL_verify_mode => 0 ); + }; } use base qw(centreon::script); From 47b4dbbd6c3d030541f1d33ce6639beb9151fcf5 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 6 Jan 2016 10:02:37 +0100 Subject: [PATCH 154/447] + fix sampling period 20 --- .../vmware/src/centreon/vmware/common.pm | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 73507a0d4..401a70881 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -208,15 +208,15 @@ sub get_perf_metric_ids { foreach (@{$options{metrics}}) { if (defined($options{connector}->{perfcounter_cache}->{$_->{label}})) { - foreach my $instance (@{$_->{instances}}) { - if ($options{connector}->{perfcounter_cache}->{$_->{label}}{level} > $options{connector}->{sampling_periods}->{$options{interval}}->{level}) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", - $_->{label}, $options{interval}, - $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, - $options{connector}->{sampling_periods}->{$options{interval}}->{level})); - return undef; - } + if ($options{interval} != 20 && $options{connector}->{perfcounter_cache}->{$_->{label}}{level} > $options{connector}->{sampling_periods}->{$options{interval}}->{level}) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", + $_->{label}, $options{interval}, + $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, + $options{connector}->{sampling_periods}->{$options{interval}}->{level})); + return undef; + } + foreach my $instance (@{$_->{instances}}) { my $metric = PerfMetricId->new(counterId => $options{connector}->{perfcounter_cache}->{$_->{label}}{key}, instance => $instance); push @$filtered_list, $metric; From 7993c47c50674754c0fe7c71ce24f689c675df2b Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 15 Jan 2016 10:20:56 +0100 Subject: [PATCH 155/447] + Fix #9 --- .../vmware/src/centreon/vmware/cmdcpuhost.pm | 12 ++-- .../vmware/src/centreon/vmware/cmdtimehost.pm | 61 ++++++++++++++++--- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index 36d760436..8db090a67 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -52,14 +52,14 @@ sub checkArgs { return 1; } if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; } if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } diff --git a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm index 3ae1adfc9..c531fba61 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm @@ -45,6 +45,19 @@ sub checkArgs { short_msg => "Argument error: esx hostname cannot be null"); return 1; } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + foreach my $label (('warning_time', 'critical_time')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } + } return 0; } @@ -56,6 +69,9 @@ sub initArgs { } $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning_time', 'critical_time')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } } sub set_connector { @@ -87,16 +103,22 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => 'Time Host(s):'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => 'All Times are ok'); + } my @host_array = (); foreach my $entity_view (@$result) { - if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->{val}) == 0) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s' is disconnected", - $entity_view->{name})); - next; - } + next if (centreon::vmware::common::host_state(connector => $self->{connector}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->{val}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); if (defined($entity_view->{'configManager.dateTimeSystem'})) { push @host_array, $entity_view->{'configManager.dateTimeSystem'}; } @@ -106,14 +128,35 @@ sub run { my $result2 = centreon::vmware::common::get_views($self->{connector}, \@host_array, \@properties); return if (!defined($result2)); + my $localtime = time(); foreach my $entity_view (@$result) { my $host_dts_value = $entity_view->{'configManager.dateTimeSystem'}->{value}; foreach my $host_dts_view (@$result2) { if ($host_dts_view->{mo_ref}->{value} eq $host_dts_value) { my $time = $host_dts_view->QueryDateTime(); my $timestamp = Date::Parse::str2time($time); - $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s': unix timestamp %s, date: %s", - $entity_view->{name}, $timestamp, $time)); + my $offset = $localtime - $timestamp; + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $offset, threshold => [ { label => 'critical_time', exit_litteral => 'critical' }, { label => 'warning_time', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' date: %s, offset: %s second(s)", + $entity_view->{name}, + $time, $offset)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Time offset %d second(s) : %s", + $entity_view->{name}, $offset, + $time)); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'offset' . $extra_label, unit => 's', + value => $offset, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_time'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_time'), + min => 0); + last; } } From 3118725303421a6baa75ff76646771e34ad2be9a Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 15 Jan 2016 10:36:10 +0100 Subject: [PATCH 156/447] + Fix #12 --- .../src/centreon/vmware/cmdalarmdatacenter.pm | 9 +++++---- .../vmware/src/centreon/vmware/cmdalarmhost.pm | 15 ++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm index ad51078c7..d05b5e85d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm @@ -126,7 +126,7 @@ sub run { my $entity = centreon::vmware::common::get_view($self->{connector}, $_->entity, ['name']); my $alarm = centreon::vmware::common::get_view($self->{connector}, $_->alarm, ['info']); - $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, + $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, entity_name => $entity->name, time => $_->time, name => $alarm->info->name, description => $alarm->info->description, status => $_->overallStatus->val}; @@ -152,11 +152,12 @@ sub run { $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", $dc_alarms->{$dc_name}->{yellow}, $dc_alarms->{$dc_name}->{red})); foreach my $alert (keys %{$dc_alarms->{$dc_name}->{alarms}}) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s", + $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s/%s", $dc_alarms->{$dc_name}->{alarms}->{$alert}->{status}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{name}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{time}, $dc_alarms->{$dc_name}->{alarms}->{$alert}->{type}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{entity_name}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{time}, + $dc_alarms->{$dc_name}->{alarms}->{$alert}->{name}, $dc_alarms->{$dc_name}->{alarms}->{$alert}->{description} )); } diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm index af9b1983d..595db46f8 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm @@ -125,10 +125,10 @@ sub run { my $entity = centreon::vmware::common::get_view($self->{connector}, $_->entity, ['name']); my $alarm = centreon::vmware::common::get_view($self->{connector}, $_->alarm, ['info']); - $host_alarms->{$host_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, name => $entity->name, - time => $_->time, name => $alarm->info->name, - description => $alarm->info->description, - status => $_->overallStatus->val}; + $host_alarms->{$host_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, entity_name => $entity->name, + time => $_->time, name => $alarm->info->name, + description => $alarm->info->description, + status => $_->overallStatus->val}; $host_alarms->{$host_view->name}->{$_->overallStatus->val}++; $total_alarms->{$_->overallStatus->val}++; } @@ -151,11 +151,12 @@ sub run { $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", $host_alarms->{$host_name}->{yellow}, $host_alarms->{$host_name}->{red})); foreach my $alert (keys %{$host_alarms->{$host_name}->{alarms}}) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s", + $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s/%s", $host_alarms->{$host_name}->{alarms}->{$alert}->{status}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{name}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{time}, $host_alarms->{$host_name}->{alarms}->{$alert}->{type}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{entity_name}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{time}, + $host_alarms->{$host_name}->{alarms}->{$alert}->{name}, $host_alarms->{$host_name}->{alarms}->{$alert}->{description} )); } From d82a27b9d9fc5202cd49fde5415d02255a65ee3b Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 15 Jan 2016 10:43:47 +0100 Subject: [PATCH 157/447] + Update changelog --- connectors/vmware/changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index b890c5301..7daf5b885 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,7 @@ +2016-01-15 Quentin Garnier - 2.2.0 + * Enhance: Can check ESX time offset (issue #9) + * Fix: displaying object name in alarm-* modes (issue #12) + 2015-12-03 Quentin Garnier - 2.1.0 * Enhance: Add a command to monitor ESX services (issue #3) * Enhance: Can choose the sampling period (issue #1) From b640d4ae9f6b47d7bf44eafd12f66abc69de908e Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 25 Jan 2016 13:45:24 +0100 Subject: [PATCH 158/447] + update version --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index c9bed5e5f..fec876488 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.0.0"; +my $VERSION = "2.2.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From 5a4a2c144ef327fe55ec1a8d07bbb4791db46bd0 Mon Sep 17 00:00:00 2001 From: Sims24 Date: Tue, 23 Feb 2016 11:49:23 +0100 Subject: [PATCH 159/447] + Update doc - fix mistype Fix error in config file syntax when defining multiple vCenter --- connectors/vmware/doc/en/exploitation/index.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/doc/en/exploitation/index.rst b/connectors/vmware/doc/en/exploitation/index.rst index 6f0b04794..6d761af30 100644 --- a/connectors/vmware/doc/en/exploitation/index.rst +++ b/connectors/vmware/doc/en/exploitation/index.rst @@ -58,11 +58,10 @@ In case you have many VirtualCenters, the configuration is (note the use of "," 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', 'password' => 'xxxx'}, - }, 'other' => {'url' => 'https://other_vcenter/sdk', 'username' => 'test@test.fr', 'password' => 'xxxx'}, - } + }, ); 'other' and 'default' are containers name. @@ -118,4 +117,4 @@ You can have the following error returns by the connector: # perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin ... Cannot get value for counters... -Please check that your VirtualCenter and ESX time synchronization. Most of the time, the server with the connector and/or VirtualCenter/ESX are not well synchronized. \ No newline at end of file +Please check that your VirtualCenter and ESX time synchronization. Most of the time, the server with the connector and/or VirtualCenter/ESX are not well synchronized. From bc01c36c46f361352fa588564a9e8e345b4f9ef7 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 26 May 2016 15:53:09 +0200 Subject: [PATCH 160/447] + Better management of deconnection issue --- connectors/vmware/src/centreon/vmware/connector.pm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 5ac753e4a..c04a41699 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -264,13 +264,15 @@ sub run { ### # Manage vpshere connection ### - if (defined($connector->{last_time_vsphere}) && defined($connector->{last_time_check}) - && $connector->{last_time_vsphere} < $connector->{last_time_check}) { + if ($connector->{vsphere_connected} == 1 && + defined($connector->{last_time_vsphere}) && defined($connector->{last_time_check}) && + $connector->{last_time_vsphere} < $connector->{last_time_check}) { $connector->{logger}->writeLogError("'" . $connector->{whoaim} . "' Disconnect"); $connector->{vsphere_connected} = 0; eval { $connector->{session1}->logout(); }; + delete $connector->{session1}; } if ($connector->{vsphere_connected} == 0) { @@ -295,7 +297,8 @@ sub run { ### # Manage session time ### - if (defined($connector->{keeper_session_time}) && + if ($connector->{vsphere_connected} == 1 && + defined($connector->{keeper_session_time}) && (time() - $connector->{keeper_session_time}) > ($connector->{config_vsphere_session_heartbeat} * 60)) { centreon::vmware::common::heartbeat(connector => $connector); } From 476af08a01b0b0a6202225cf6a0644991208a153 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 26 May 2016 15:53:35 +0200 Subject: [PATCH 161/447] + Add max-total-latency for datastore-vm --- .../src/centreon/vmware/cmddatastorevm.pm | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 280b03182..7e2bae5fc 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -63,7 +63,7 @@ sub checkArgs { short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); return 1; } - foreach my $label (('warning', 'critical')) { + foreach my $label (('warning', 'critical', 'warning_max_total_latency', 'critical_max_total_latency')) { if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); @@ -81,7 +81,7 @@ sub initArgs { } $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical')) { + foreach my $label (('warning', 'critical', 'warning_max_total_latency', 'critical_max_total_latency')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); } } @@ -171,19 +171,20 @@ sub run { #if ($_->info->isa('NasDatastoreInfo')) { # Zero disk Info #} - } - + } + # Vsphere >= 4.1 # We don't filter. To filter we'll need to get disk from vms my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, - [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, - {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + [{label => 'disk.numberRead.summation', instances => ['*']}, + {label => 'disk.numberWrite.summation', instances => ['*']}, + {label => 'disk.maxTotalLatency.latest', instances => ['']}], $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - + my $interval_sec = $self->{connector}->{perfcounter_speriod}; if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { $interval_sec = $self->{sampling_period}; @@ -215,6 +216,8 @@ sub run { $datastore_lun{$disk_name{$disk_name}}->{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}; } + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); foreach (sort keys %datastore_lun) { $finded |= 2; my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $interval_sec)); @@ -237,8 +240,6 @@ sub run { $prefix_msg, $_, $write_counter)); } - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); $self->{manager}->{output}->perfdata_add(label => 'riops' . $extra_label . '_' . $_, unit => 'iops', value => $read_counter, warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), @@ -250,6 +251,21 @@ sub run { critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); } + + my $max_total_latency = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'disk.maxTotalLatency.latest'}->{key} . ":"})); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $max_total_latency, threshold => [ { label => 'critical_max_total_latency', exit_litteral => 'critical' }, { label => 'warning_max_total_latency', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("%s max total latency is %s ms", + $prefix_msg, $max_total_latency)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s max total latency is %s ms", + $prefix_msg, $max_total_latency)); + } + $self->{manager}->{output}->perfdata_add(label => 'max_total_latency' . $extra_label, unit => 'ms', + value => $max_total_latency, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_max_total_latency'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_max_total_latency'), + min => 0); } if (($finded & 2) == 0) { From 3b8e696fc5dce5a6a4076992ffc92286244e5a5d Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 26 May 2016 15:56:52 +0200 Subject: [PATCH 162/447] + update changelog --- connectors/vmware/changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 7daf5b885..eb24bad85 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,7 @@ +2016-05-26 Quentin Garnier - 2.2.1 + * Enhance: Better management of ESX/VCenter disconnect + * Enhance: Add counter 'max-total-latency' for mode 'datastore-vm' + 2016-01-15 Quentin Garnier - 2.2.0 * Enhance: Can check ESX time offset (issue #9) * Fix: displaying object name in alarm-* modes (issue #12) From b46f3fa5c8255c8ccd1df51cd8c2d85d3496c42d Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 26 May 2016 16:32:38 +0200 Subject: [PATCH 163/447] + Change version --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index fec876488..01df9c050 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.2.0"; +my $VERSION = "2.2.1"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From 732be2041d71179367f8678733421cc93a59f921 Mon Sep 17 00:00:00 2001 From: rwerquin Date: Tue, 12 Jul 2016 14:50:31 +0200 Subject: [PATCH 164/447] add systemd script --- .../packaging/redhat/centreon_vmware-systemd | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 connectors/vmware/packaging/redhat/centreon_vmware-systemd diff --git a/connectors/vmware/packaging/redhat/centreon_vmware-systemd b/connectors/vmware/packaging/redhat/centreon_vmware-systemd new file mode 100644 index 000000000..0ed2bf8fe --- /dev/null +++ b/connectors/vmware/packaging/redhat/centreon_vmware-systemd @@ -0,0 +1,27 @@ +## Copyright 2016 Centreon +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## +## For more information : contact@centreon.com +## + +[Unit] +Description=Centreon VMWare + +[Service] +ExecStart=/usr/bin/perl /usr/bin/centreon_vmware.pl --logfile=/var/log/centreon/centreon_vmware.log --severity=error +Type=simple +User=root + +[Install] +WantedBy=multi-user.target From 27a3fc92c9a6bd4177f4173ea3597b5b7f14e5c4 Mon Sep 17 00:00:00 2001 From: Marcel Hecko Date: Thu, 21 Jul 2016 15:22:54 +0200 Subject: [PATCH 165/447] Update common.pm --- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 401a70881..6eb20c52b 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -352,7 +352,7 @@ sub generic_performance_values_historic { if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Cannot get value for counters (Maybe, object(s) cannot be reached: disconnected, not running,...)'); + short_msg => 'Cannot get value for counters (Maybe, object(s) cannot be reached: disconnected, not running, time not synced (see time-host mode),...)'); return undef; } foreach my $val (@$perfdata) { From 326e133e2c12e4d762a0cbdb9a4f77221c2bca44 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 2 Aug 2016 11:14:59 +0200 Subject: [PATCH 166/447] + change some zmq api functions --- .../src/centreon/script/centreon_vmware.pm | 33 ++++++++++++++----- .../vmware/src/centreon/vmware/common.pm | 12 +++++-- .../vmware/src/centreon/vmware/connector.pm | 9 +++-- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 01df9c050..7f9c86410 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -363,9 +363,14 @@ sub request_dynamic { identity => $options{identity}) == 0); $self->{centreon_vmware_config}->{vsphere_server}->{$container}->{last_request} = time(); + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; - zmq_sendmsg($frontend, "server-" . $container, $flag); - zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); + my $msg = zmq_msg_init_data("server-" . $container); + zmq_msg_send($msg, $frontend, $flag); + zmq_msg_close($msg); + $msg = zmq_msg_init_data('REQCLIENT ' . $options{data}); + zmq_msg_send($msg, $frontend, ZMQ_NOBLOCK); + zmq_msg_close($msg); } sub request { @@ -417,9 +422,14 @@ sub request { identity => $options{identity}) == 0); $self->{counter_stats}->{$result->{container}}++; + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; - zmq_sendmsg($frontend, "server-" . $result->{container}, $flag); - zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); + my $msg = zmq_msg_init_data("server-" . $result->{container}); + zmq_msg_send($msg, $frontend, $flag); + zmq_msg_close($msg); + $msg = zmq_msg_init_data('REQCLIENT ' . $options{data}); + zmq_msg_send($msg, $frontend, ZMQ_NOBLOCK); + zmq_msg_close($msg); } sub repserver { @@ -445,11 +455,15 @@ sub repserver { sub router_event { while (1) { # Process all parts of the message - my $message = zmq_recvmsg($frontend); - my $identity = zmq_msg_data($message); - $message = zmq_recvmsg($frontend); - - my $data = zmq_msg_data($message); + my $msg = zmq_msg_init(); + zmq_msg_recv($msg, $frontend, ZMQ_DONTWAIT); + my $identity = zmq_msg_data($msg); + zmq_msg_close($msg); + + $msg = zmq_msg_init(); + zmq_msg_recv($msg, $frontend, ZMQ_DONTWAIT); + my $data = zmq_msg_data($msg); + zmq_msg_close($msg); my $manager = centreon::vmware::common::init_response(); if ($centreon_vmware->{stop} != 0) { @@ -466,6 +480,7 @@ sub router_event { $centreon_vmware->{centreon_vmware_config}->{vsphere_server}->{$1}->{ready} = 1; } + centreon::vmware::common::free_response(); my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE); last unless $more; } diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 6eb20c52b..53fa6cdff 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -40,6 +40,10 @@ sub init_response { return $manager_display; } +sub free_response { + $manager_display = {}; +} + sub response { my (%options) = @_; @@ -62,9 +66,13 @@ sub response { zmq_setsockopt($options{endpoint}, ZMQ_LINGER, 10000); } if (defined($options{identity})) { - zmq_sendmsg($options{endpoint}, $options{identity}, $flag); + my $msg = zmq_msg_init_data($options{identity}); + zmq_msg_send($msg, $options{endpoint}, $flag); + zmq_msg_close($msg); } - zmq_sendmsg($options{endpoint}, $options{token} . " " . $stdout, ZMQ_NOBLOCK); + my $msg = zmq_msg_init_data($options{token} . " " . $stdout); + zmq_msg_send($msg, $options{endpoint}, ZMQ_NOBLOCK); + zmq_msg_close($msg); } sub vmware_error { diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index c04a41699..c1efab7e2 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -130,6 +130,7 @@ sub response_router { short_msg => $options{msg}); $manager->{output}->{plugin} = $options{identity}; centreon::vmware::common::response(token => 'RESPSERVER2', endpoint => $backend); + centreon::vmware::common::free_response(); } sub verify_child { @@ -198,12 +199,14 @@ sub reqclient { sub vsphere_event { while (1) { # Process all parts of the message - my $message = zmq_recvmsg($backend); - if (!defined($message)) { + my $msg = zmq_msg_init(); + my $rv = zmq_msg_recv($msg, $backend, undef); + if ($rv == -1) { $connector->{logger}->writeLogError("zmq_recvmsg error: $!"); last; } - my $data = zmq_msg_data($message); + my $data = zmq_msg_data($msg); + zmq_msg_close($msg); if ($data =~ /^REQCLIENT\s+(.*)$/msi) { $connector->reqclient(data => $1); From cc2fcecfa33e1d6c256112ea321874ba92ece8d3 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 2 Aug 2016 17:42:51 +0200 Subject: [PATCH 167/447] + factorize some code --- .../src/centreon/script/centreon_vmware.pm | 2 +- .../src/centreon/vmware/cmdalarmdatacenter.pm | 21 +++------ .../src/centreon/vmware/cmdalarmhost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdbase.pm | 45 +++++++++++++++++++ .../src/centreon/vmware/cmdcountvmhost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdcpuhost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdcpuvm.pm | 21 +++------ .../centreon/vmware/cmddatastorecountvm.pm | 21 +++------ .../src/centreon/vmware/cmddatastorehost.pm | 21 +++------ .../src/centreon/vmware/cmddatastoreio.pm | 21 +++------ .../src/centreon/vmware/cmddatastoreiops.pm | 21 +++------ .../centreon/vmware/cmddatastoresnapshot.pm | 21 +++------ .../src/centreon/vmware/cmddatastoreusage.pm | 21 +++------ .../src/centreon/vmware/cmddatastorevm.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdgetmap.pm | 21 +++------ .../src/centreon/vmware/cmdhealthhost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdlimitvm.pm | 21 +++------ .../src/centreon/vmware/cmdlistdatacenters.pm | 21 +++------ .../src/centreon/vmware/cmdlistdatastores.pm | 21 +++------ .../src/centreon/vmware/cmdlistnichost.pm | 21 +++------ .../src/centreon/vmware/cmdmaintenancehost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdmemhost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdmemvm.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdnethost.pm | 22 +++------ .../src/centreon/vmware/cmdservicehost.pm | 21 +++------ .../src/centreon/vmware/cmdsnapshotvm.pm | 21 +++------ .../src/centreon/vmware/cmdstatushost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdstatusvm.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdswaphost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdswapvm.pm | 21 +++------ .../centreon/vmware/cmdthinprovisioningvm.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdtimehost.pm | 21 +++------ .../vmware/src/centreon/vmware/cmdtoolsvm.pm | 21 +++------ .../src/centreon/vmware/cmduptimehost.pm | 21 +++------ .../centreon/vmware/cmdvmoperationcluster.pm | 21 +++------ 35 files changed, 244 insertions(+), 497 deletions(-) create mode 100644 connectors/vmware/src/centreon/vmware/cmdbase.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 7f9c86410..b18507cbc 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -262,7 +262,7 @@ sub load_module { for (@_) { (my $file = "$_.pm") =~ s{::}{/}g; require $file; - my $obj = $_->new($self->{logger}); + my $obj = $_->new(logger => $self->{logger}); $self->{modules_registry}->{$obj->getCommandName()} = $obj; } } diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm index d05b5e85d..52953906f 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm @@ -18,6 +18,8 @@ package centreon::vmware::cmdalarmdatacenter; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; @@ -25,20 +27,15 @@ use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'alarmdatacenter'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -62,12 +59,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm index 595db46f8..5a61e69a1 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm @@ -18,6 +18,8 @@ package centreon::vmware::cmdalarmhost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; @@ -25,20 +27,15 @@ use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'alarmhost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -62,12 +59,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm new file mode 100644 index 000000000..9d33ca6dd --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -0,0 +1,45 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdbase; + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{logger} = $options{logger}; + + return $self; +} + +sub getCommandName { + my $self = shift; + return $self->{commandName}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{connector} = $options{connector}; +} + +1; diff --git a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm index 5b0402eb6..b750be4dd 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdcountvmhost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'countvmhost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index 8db090a67..0cf5a084b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdcpuhost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'cpuhost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -76,12 +73,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 21828e001..f1bdc0abe 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdcpuvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'cpuvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -80,12 +77,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm index 352a6e2d5..f7ae0476a 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmddatastorecountvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastorecountvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm index 11c298d50..b00344914 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm @@ -18,26 +18,23 @@ package centreon::vmware::cmddatastorehost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use File::Basename; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastorehost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -80,12 +77,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm index 66108d125..ca9f0f6b3 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmddatastoreio; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastoreio'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 5839e28c0..490cbd5e6 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmddatastoreiops; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastoreiops'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm index cc704846b..45bc17133 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmddatastoresnapshot; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastoresnapshot'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index 5f80a9fd6..1b78eb6ef 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmddatastoreusage; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastoreusage'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -78,12 +75,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 7e2bae5fc..d8d989565 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -18,26 +18,23 @@ package centreon::vmware::cmddatastorevm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; use File::Basename; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'datastorevm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -86,12 +83,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm index 3b98a61f2..e6afd9808 100644 --- a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdgetmap; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'getmap'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -58,12 +55,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm index 870ebd91c..0ba3e5397 100644 --- a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdhealthhost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'healthhost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -66,12 +63,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index 823fbdfff..6c47929fe 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdlimitvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'limitvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -82,12 +79,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub display_verbose { my ($self, %options) = @_; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm index 577b8d742..79d8407cd 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdlistdatacenters; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'listdatacenters'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -58,12 +55,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm index 1575372e6..a221ba219 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdlistdatastores; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'listdatastores'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -58,12 +55,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm index c9c46c69c..d0f4ef9ce 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdlistnichost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'listnichost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -58,12 +55,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; my %nic_in_vswitch = (); diff --git a/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm index 987fa8adb..2cd2095aa 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdmaintenancehost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'maintenancehost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -70,12 +67,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index 77d7287c4..42d3f9ca6 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdmemhost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'memhost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -76,12 +73,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index 9b4e952c9..1aa22444a 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdmemvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'memvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -82,12 +79,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index e7407bad9..52bc4a25f 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -18,26 +18,22 @@ package centreon::vmware::cmdnethost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'nethost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - - sub checkArgs { my ($self, %options) = @_; @@ -86,12 +82,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm index f2ed9d966..c46baf588 100644 --- a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdservicehost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'servicehost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -64,12 +61,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm index ec855e091..da068ac0b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdsnapshotvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'snapshotvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm index 46b146e29..1ce5d361c 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdstatushost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'statushost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -64,12 +61,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm index d4e389022..eec24446d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdstatusvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'statusvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -64,12 +61,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm index a2f627e26..58ac8feb8 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdswaphost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'swaphost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -76,12 +73,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm index e75897ab0..a2c28178e 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdswapvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'swapvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -82,12 +79,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index 974cb1e45..dc2f08552 100644 --- a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdthinprovisioningvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'thinprovisioningvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -71,12 +68,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub display_verbose { my ($self, %options) = @_; diff --git a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm index c531fba61..ed11260f3 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdtimehost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'timehost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -74,12 +71,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index 60d4026d7..9ad8aa312 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmdtoolsvm; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'toolsvm'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -82,12 +79,6 @@ sub initArgs { $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub display_verbose { my ($self, %options) = @_; diff --git a/connectors/vmware/src/centreon/vmware/cmduptimehost.pm b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm index 25b5b974e..cdd41764f 100644 --- a/connectors/vmware/src/centreon/vmware/cmduptimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm @@ -18,25 +18,22 @@ package centreon::vmware::cmduptimehost; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'uptimehost'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -76,12 +73,6 @@ sub initArgs { $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm index 822a926b3..0548bf0a4 100644 --- a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm @@ -18,6 +18,8 @@ package centreon::vmware::cmdvmoperationcluster; +use base qw(centreon::vmware::cmdbase); + use strict; use warnings; use centreon::vmware::common; @@ -25,20 +27,15 @@ use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); sub new { - my $class = shift; - my $self = {}; - $self->{logger} = shift; + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + $self->{commandName} = 'vmoperationcluster'; - bless $self, $class; return $self; } -sub getCommandName { - my $self = shift; - return $self->{commandName}; -} - sub checkArgs { my ($self, %options) = @_; @@ -72,12 +69,6 @@ sub initArgs { } } -sub set_connector { - my ($self, %options) = @_; - - $self->{connector} = $options{connector}; -} - sub run { my $self = shift; From 11aff4cf63f9af5d2421e98976e5abfa571fbc02 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 2 Aug 2016 17:54:37 +0200 Subject: [PATCH 168/447] + add autokill system for childs --- .../vmware/src/centreon/vmware/cmdbase.pm | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index 9d33ca6dd..5c72067f4 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -21,6 +21,8 @@ package centreon::vmware::cmdbase; use strict; use warnings; +my %handlers = (ALRM => {}); + sub new { my ($class, %options) = @_; my $self = {}; @@ -36,10 +38,32 @@ sub getCommandName { return $self->{commandName}; } +sub set_signal_handlers { + my $self = shift; + + $SIG{ALRM} = \&class_handle_ALRM; + $handlers{ALRM}->{$self} = sub { $self->handle_ALRM() }; +} + +sub class_handle_ALRM { + foreach (keys %{$handlers{ALRM}}) { + &{$handlers{ALRM}->{$_}}(); + } +} + +sub handle_ALRM { + my $self = shift; + + $self->{logger}->writeLogError("Child process autokill!!"); + exit(0); +} + sub set_connector { my ($self, %options) = @_; $self->{connector} = $options{connector}; + $self->set_signal_handlers(); + alarm(300); } 1; From 5ba137ab57ab296cd4243b5d21fb83b433d663e4 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 3 Aug 2016 14:37:29 +0200 Subject: [PATCH 169/447] + Fix #14 --- .../src/centreon/script/centreon_vmware.pm | 3 ++- .../src/centreon/vmware/cmdalarmdatacenter.pm | 13 ++-------- .../src/centreon/vmware/cmdalarmhost.pm | 12 ++-------- .../vmware/src/centreon/vmware/cmdbase.pm | 24 +++++++++++++++++++ .../src/centreon/vmware/cmdcountvmhost.pm | 11 ++------- .../vmware/src/centreon/vmware/cmdcpuhost.pm | 12 ++-------- .../vmware/src/centreon/vmware/cmdcpuvm.pm | 13 +++------- .../centreon/vmware/cmddatastorecountvm.pm | 11 ++------- .../src/centreon/vmware/cmddatastorehost.pm | 11 ++------- .../src/centreon/vmware/cmddatastoreio.pm | 11 ++------- .../src/centreon/vmware/cmddatastoreiops.pm | 11 ++------- .../centreon/vmware/cmddatastoresnapshot.pm | 11 ++------- .../src/centreon/vmware/cmddatastoreusage.pm | 11 ++------- .../src/centreon/vmware/cmddatastorevm.pm | 13 +++------- .../vmware/src/centreon/vmware/cmdgetmap.pm | 12 ++-------- .../src/centreon/vmware/cmdhealthhost.pm | 13 ++-------- .../vmware/src/centreon/vmware/cmdlimitvm.pm | 13 +++------- .../src/centreon/vmware/cmdlistdatacenters.pm | 12 ++-------- .../src/centreon/vmware/cmdlistdatastores.pm | 12 ++-------- .../src/centreon/vmware/cmdlistnichost.pm | 4 ++-- .../src/centreon/vmware/cmdmaintenancehost.pm | 12 ++-------- .../vmware/src/centreon/vmware/cmdmemhost.pm | 11 ++------- .../vmware/src/centreon/vmware/cmdmemvm.pm | 13 +++------- .../vmware/src/centreon/vmware/cmdnethost.pm | 11 ++------- .../src/centreon/vmware/cmdservicehost.pm | 12 ++-------- .../src/centreon/vmware/cmdsnapshotvm.pm | 13 +++------- .../src/centreon/vmware/cmdstatushost.pm | 12 ++-------- .../vmware/src/centreon/vmware/cmdstatusvm.pm | 14 +++-------- .../vmware/src/centreon/vmware/cmdswaphost.pm | 11 ++------- .../vmware/src/centreon/vmware/cmdswapvm.pm | 17 ++++--------- .../centreon/vmware/cmdthinprovisioningvm.pm | 13 +++------- .../vmware/src/centreon/vmware/cmdtimehost.pm | 12 ++-------- .../vmware/src/centreon/vmware/cmdtoolsvm.pm | 13 +++------- .../src/centreon/vmware/cmduptimehost.pm | 13 +++------- .../centreon/vmware/cmdvmoperationcluster.pm | 11 ++------- 35 files changed, 104 insertions(+), 317 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index b18507cbc..440ffeae6 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -120,6 +120,7 @@ sub new { vm_state_error => 'UNKNOWN', host_state_error => 'UNKNOWN', retention_dir => '/var/lib/centreon/centplugins', + case_insensitive => 0, vsphere_server => { #'default' => {'url' => 'https://XXXXXX/sdk', # 'username' => 'XXXXX', @@ -262,7 +263,7 @@ sub load_module { for (@_) { (my $file = "$_.pm") =~ s{::}{/}g; require $file; - my $obj = $_->new(logger => $self->{logger}); + my $obj = $_->new(logger => $self->{logger}, case_insensitive => $self->{centreon_vmware_config}->{case_insensitive}); $self->{modules_registry}->{$obj->getCommandName()} = $obj; } } diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm index 52953906f..d660ad6b6 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm @@ -71,25 +71,16 @@ sub run { return if ($self->{statefile_cache}->error() == 1); } - my %filters = (); my $multiple = 0; - if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{connector}->{module_date_parse_loaded} == 0) { $self->{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Need to install Date::Parse CPAN Module"); return ; } - if (defined($self->{datacenter}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datacenter}\E$/; - } elsif (!defined($self->{datacenter})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datacenter}/; - } - + my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); my @properties = ('name', 'triggeredAlarmState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm index 5a61e69a1..92b6f106d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm @@ -71,7 +71,6 @@ sub run { return if ($self->{statefile_cache}->error() == 1); } - my %filters = (); my $multiple = 0; if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{connector}->{module_date_parse_loaded} == 0) { @@ -80,16 +79,9 @@ sub run { return ; } - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } - + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'triggeredAlarmState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index 5c72067f4..b9021df23 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -29,6 +29,7 @@ sub new { bless $self, $class; $self->{logger} = $options{logger}; + $self->{case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; return $self; } @@ -66,4 +67,27 @@ sub set_connector { alarm(300); } +sub build_filter { + my ($self, %options) = @_; + + my $filters = {}; + if (defined($self->{$options{search_option}}) && !defined($self->{$options{is_regexp}})) { + if ($self->{case_insensitive} == 1) { + $filters->{name} = qr/^\Q$self->{$options{search_option}}\E$/i; + } else { + $filters->{name} = qr/^\Q$self->{$options{search_option}}\E$/; + } + } elsif (!defined($self->{$options{search_option}})) { + $filters->{name} = qr/.*/; + } else { + if ($self->{case_insensitive} == 1) { + $filters->{name} = qr/$self->{$options{search_option}}/i; + } else { + $filters->{name} = qr/$self->{$options{search_option}}/; + } + } + + return $filters; +} + 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm index b750be4dd..7262f48f7 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm @@ -74,17 +74,10 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'vm', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index 0cf5a084b..01508faec 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -82,18 +82,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } - + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.connectionState', 'summary.hardware.numCpuCores', 'summary.hardware.cpuMhz'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index f1bdc0abe..7f9161121 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -86,24 +86,17 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); my @instances = ('*'); diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm index f7ae0476a..2426c793e 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm @@ -74,17 +74,10 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{datastore_name}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datastore_name}\E$/; - } elsif (!defined($self->{datastore_name})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datastore_name}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.name', 'vm', 'summary.accessible'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm index b00344914..567cf9b71 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm @@ -86,17 +86,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'config.fileSystemVolume.mountInfo', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm index ca9f0f6b3..ee1b66bf8 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm @@ -80,17 +80,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{datastore_name}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datastore_name}\E$/; - } elsif (!defined($self->{datastore_name})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datastore_name}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.name', 'summary.accessible'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 490cbd5e6..e03cd012c 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -80,17 +80,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{datastore_name}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datastore_name}\E$/; - } elsif (!defined($self->{datastore_name})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datastore_name}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm index 45bc17133..70d1385b2 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm @@ -74,17 +74,10 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{datastore_name}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datastore_name}\E$/; - } elsif (!defined($self->{datastore_name})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datastore_name}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.accessible', 'summary.name', 'browser'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index 1b78eb6ef..9c48cd711 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -78,18 +78,11 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{datastore_name}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datastore_name}\E$/; - } elsif (!defined($self->{datastore_name})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datastore_name}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index d8d989565..b323956f0 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -92,24 +92,17 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'datastore', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm index e6afd9808..f62ac294f 100644 --- a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm @@ -58,17 +58,9 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); - - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'vm', 'config.product.version'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); $self->{manager}->{output}->output_add(severity => 'OK', diff --git a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm index 0ba3e5397..f1d860cb0 100644 --- a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm @@ -66,20 +66,11 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } - + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index 6c47929fe..a495034f9 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -95,17 +95,10 @@ sub display_verbose { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); @@ -116,7 +109,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm index 79d8407cd..40c0f2ff4 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm @@ -58,19 +58,11 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{datacenter}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datacenter}\E$/; - } elsif (!defined($self->{datacenter})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datacenter}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); my @properties = ('name'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => $filters); return if (!defined($result)); if (!defined($self->{disco_show})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm index a221ba219..5a2e00f94 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm @@ -58,19 +58,11 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{datastore_name}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{datastore_name}\E$/; - } elsif (!defined($self->{datastore_name})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{datastore_name}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); if (!defined($self->{disco_show})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm index d0f4ef9ce..d95c4d35f 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm @@ -59,9 +59,9 @@ sub run { my $self = shift; my %nic_in_vswitch = (); - my %filters = (name => $self->{esx_hostname}); + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('config.network.pnic', 'config.network.vswitch', 'config.network.proxySwitch'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); # Get Name from vswitch diff --git a/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm index 2cd2095aa..5f7d7781a 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm @@ -70,19 +70,11 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.inMaintenanceMode', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index 42d3f9ca6..9b776eaf4 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -82,17 +82,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'summary.hardware.memorySize', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index 1aa22444a..075a7b08e 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -88,24 +88,17 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index 52bc4a25f..5a16e2244 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -91,20 +91,13 @@ sub run { return ; } - my %filters = (); my ($multiple, $number_nic) = (0, 0); - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'config.network.pnic', 'runtime.connectionState', 'config.network.vswitch'); if (!defined($self->{no_proxyswitch})) { push @properties, 'config.network.proxySwitch'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm index c46baf588..24a180931 100644 --- a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm @@ -64,18 +64,10 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.connectionState', 'runtime.inMaintenanceMode', 'configManager.serviceSystem'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); my %host_names = (); diff --git a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm index da068ac0b..43add42a1 100644 --- a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm @@ -80,17 +80,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'); @@ -101,7 +94,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); my %vm_consolidate = (); diff --git a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm index 1ce5d361c..6031c5f85 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm @@ -64,18 +64,10 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm index eec24446d..ea07c3b45 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm @@ -64,24 +64,16 @@ sub initArgs { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm index 58ac8feb8..1956635e1 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm @@ -82,17 +82,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm index a2c28178e..e20af75f9 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -88,17 +88,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); @@ -106,7 +99,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, @@ -140,8 +133,8 @@ sub run { my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"})) * 1024; my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"})) * 1024; - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); diff --git a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index dc2f08552..17ca1a231 100644 --- a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -86,17 +86,10 @@ sub display_verbose { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'config.hardware.device', 'runtime.connectionState', 'runtime.powerState'); @@ -104,7 +97,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm index ed11260f3..d6f7014a7 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm @@ -80,19 +80,11 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'configManager.dateTimeSystem', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index 9ad8aa312..862a13ce2 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -95,17 +95,10 @@ sub display_verbose { sub run { my $self = shift; - my %filters = (); my $multiple = 0; - if (defined($self->{vm_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{vm_hostname}\E$/; - } elsif (!defined($self->{vm_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{vm_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters{'config.annotation'} = qr/$self->{filter_description}/; + $filters->{'config.annotation'} = qr/$self->{filter_description}/; } my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); @@ -113,7 +106,7 @@ sub run { push @properties, 'config.annotation'; } - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmduptimehost.pm b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm index cdd41764f..321795c68 100644 --- a/connectors/vmware/src/centreon/vmware/cmduptimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm @@ -82,17 +82,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{esx_hostname}) && !defined($self->{filter})) { - $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; - } elsif (!defined($self->{esx_hostname})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{esx_hostname}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.bootTime', 'runtime.connectionState'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { @@ -120,7 +113,7 @@ sub run { my $diff_time = time() - $create_time; my $days = int($diff_time / 60 / 60 / 24); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Uptime: %s day(s)", $entity_view->{name}, $days)); diff --git a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm index 0548bf0a4..28909261b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm @@ -85,17 +85,10 @@ sub run { return ; } - my %filters = (); my $multiple = 0; - if (defined($self->{cluster}) && !defined($self->{cluster})) { - $filters{name} = qr/^\Q$self->{cluster}\E$/; - } elsif (!defined($self->{cluster})) { - $filters{name} = qr/.*/; - } else { - $filters{name} = qr/$self->{cluster}/; - } + my $filters = $self->build_filter(label => 'name', search_option => 'cluster', is_regexp => 'filter'); my @properties = ('name'); - my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => \%filters); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); return if (!defined($result)); if (scalar(@$result) > 1) { From b0892839251d8ac4a2cd5a3e98f124ede841d186 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 3 Aug 2016 15:19:54 +0200 Subject: [PATCH 170/447] + add memory state for esxi --- .../vmware/src/centreon/vmware/cmdmemhost.pm | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index 9b776eaf4..b1d342ee0 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -48,15 +48,12 @@ sub checkArgs { short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; + foreach my $label (('warning', 'critical', 'warning_state', 'critical_state')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } @@ -69,8 +66,9 @@ sub initArgs { } $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); + foreach my $label (('warning', 'critical', 'warning_state', 'critical_state')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } } sub run { @@ -94,12 +92,20 @@ sub run { my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'mem.consumed.average', 'instances' => ['']}, - {'label' => 'mem.overhead.average', 'instances' => ['']}], + {'label' => 'mem.overhead.average', 'instances' => ['']}, + {'label' => 'mem.state.latest', 'instances' => ['']}], $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + # for mem.state: + # 0 (high) Free memory >= 6% of machine memory minus Service Console memory. + # 1 (soft) 4% + # 2 (hard) 2% + # 3 (low) 1% + my %mapping_state = (0 => 'high', 1 => 'soft', 2 => 'hard', 3 => 'low'); + if ($multiple == 1) { $self->{manager}->{output}->output_add(severity => 'OK', short_msg => sprintf("All memory usages are ok")); @@ -116,20 +122,22 @@ sub run { # in KB my $mem_used = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"})) * 1024; my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"})) * 1024; + my $mem_state = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"})) * 1024; my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; my $prct_free = 100 - $prct_used; - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_used); my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%) - Memory state : %s", $entity_view->{name}, $total_value . " " . $total_unit, $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); + $free_value . " " . $free_unit, $prct_free, + $mapping_state{$mem_state})); if ($multiple == 0 || !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{manager}->{output}->output_add(severity => $exit, @@ -139,6 +147,13 @@ sub run { $used_value . " " . $used_unit, $prct_used, $free_value . " " . $free_unit, $prct_free)); } + + $exit = $self->{manager}->{perfdata}->threshold_check(value => $mem_state, threshold => [ { label => 'critical_state', exit_litteral => 'critical' }, { label => 'warning_state', exit_litteral => 'warning' } ]); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("Memory state : %s", $mapping_state{$mem_state})); + } my $extra_label = ''; $extra_label = '_' . $entity_view->{name} if ($multiple == 1); @@ -150,6 +165,11 @@ sub run { $self->{manager}->{output}->perfdata_add(label => 'overhead' . $extra_label, unit => 'B', value => $mem_overhead, min => 0); + $self->{manager}->{output}->perfdata_add(label => 'state' . $extra_label, + value => $mem_state, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_state'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_state'), + min => 0, max => 3); } } From 841c5cd711136e79e040a6557e9cded2e90897dc Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 3 Aug 2016 15:44:55 +0200 Subject: [PATCH 171/447] + add memory state --- .../vmware/src/centreon/vmware/cmdmemhost.pm | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index b1d342ee0..02f832430 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -127,32 +127,43 @@ sub run { my $prct_used = $mem_used * 100 / $memory_size; my $prct_free = 100 - $prct_used; - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_used); my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%) - Memory state : %s", - $entity_view->{name}, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free, - $mapping_state{$mem_state})); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $entity_view->{name}, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my $output = sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{manager}->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $mem_state, threshold => [ { label => 'critical_state', exit_litteral => 'critical' }, { label => 'warning_state', exit_litteral => 'warning' } ]); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $output = sprintf("Memory state : %s", $mapping_state{$mem_state}); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $mem_state, threshold => [ { label => 'critical_state', exit_litteral => 'critical' }, { label => 'warning_state', exit_litteral => 'warning' } ]); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{manager}->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + my $prefix_msg = "'$entity_view->{name}'"; + $self->{manager}->{output}->output_add(long_msg => "$prefix_msg $long_msg"); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("Memory state : %s", $mapping_state{$mem_state})); + short_msg => "$prefix_msg $short_msg" + ); + } + if ($multiple == 0) { + $self->{manager}->{output}->output_add(short_msg => "$prefix_msg $long_msg"); } my $extra_label = ''; From 280e475edff9843354ea6700d4253c1c1e9e2024 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 4 Aug 2016 11:31:01 +0200 Subject: [PATCH 172/447] + Fix #20 --- .../src/centreon/script/centreon_vmware.pm | 1 + .../vmware/src/centreon/vmware/cmddevicevm.pm | 145 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 connectors/vmware/src/centreon/vmware/cmddevicevm.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 440ffeae6..4b73e295e 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -70,6 +70,7 @@ my @load_modules = ( 'centreon::vmware::cmddatastoresnapshot', 'centreon::vmware::cmddatastorevm', 'centreon::vmware::cmddatastoreusage', + 'centreon::vmware::cmddevicevm', 'centreon::vmware::cmdgetmap', 'centreon::vmware::cmdhealthhost', 'centreon::vmware::cmdlimitvm', diff --git a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm new file mode 100644 index 000000000..f39aba832 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm @@ -0,0 +1,145 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmddevicevm; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'devicevm'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: vm hostname cannot be null"); + return 1; + } + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); + return 1; + } + if (defined($options{arguments}->{nopoweredon_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::vmware::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +sub run { + my $self = shift; + + if (!($self->{connector}->{perfcounter_speriod} > 0)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); + return ; + } + + my $multiple = 0; + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); + if (defined($self->{filter_description}) && $self->{filter_description} ne '') { + $filters->{'config.annotation'} = qr/$self->{filter_description}/; + } + + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.hardware.device'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } + + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + + my $total_device_connected = 0; + foreach my $entity_view (@$result) { + next if (centreon::vmware::common::vm_state(connector => $self->{connector}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + power => $entity_view->{'runtime.powerState'}->val, + status => $self->{disconnect_status}, + powerstatus => $self->{nopoweredon_status}, + multiple => $multiple) == 0); + + foreach my $dev (@{$entity_view->{'config.hardware.device'}}) { + if (ref($dev) =~ /$self->{device}/) { + if ($dev->connectable->connected == 1) { + my $prefix_msg = "'$entity_view->{name}'"; + if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && + $entity_view->{'config.annotation'} ne '') { + $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; + } + $self->{manager}->{output}->output_add(long_msg => sprintf("%s device connected", + $prefix_msg)); + $total_device_connected++; + } + } + } + } + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_device_connected, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("%s %s device connected", $total_device_connected, $self->{device})); + $self->{manager}->{output}->perfdata_add(label => 'connected', + value => $total_device_connected, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); +} + +1; From 113d23bb4cd99a745d9073ee21d3cabf0a04921c Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 4 Aug 2016 11:38:20 +0200 Subject: [PATCH 173/447] + Prepare new version --- connectors/vmware/changelog | 6 ++++++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index eb24bad85..1c33022c6 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,9 @@ +2016-08-04 Quentin Garnier - 2.3.0 + * Enhance: Add a mode to check connected device (issue #20) + * Enhance: Option to use case-insensitive search (issue #14) + * Enhance: Add memory state for ESX check + * Fix: Hardening connector about blocked childs + 2016-05-26 Quentin Garnier - 2.2.1 * Enhance: Better management of ESX/VCenter disconnect * Enhance: Add counter 'max-total-latency' for mode 'datastore-vm' diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 4b73e295e..468526601 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.2.1"; +my $VERSION = "2.3.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From 92374457de349a67d3a057a5ca1e226a397fe5c4 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 11 Aug 2016 10:40:15 +0200 Subject: [PATCH 174/447] + Fix doc --- connectors/vmware/doc/fr/exploitation/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index 2953e8e10..7b4e12208 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -59,7 +59,6 @@ Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', 'password' => 'xxxx'}, - }, 'other' => {'url' => 'https://other_vcenter/sdk', 'username' => 'test@test.fr', 'password' => 'xxxx'}, From 105e194af69312f8d856fdf32baf4f2670384bd0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 17 Nov 2016 17:31:22 +0100 Subject: [PATCH 175/447] + add an option to not check memory state --- .../vmware/src/centreon/vmware/cmdmemhost.pm | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index 02f832430..df74121dc 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -89,11 +89,13 @@ sub run { if (scalar(@$result) > 1) { $multiple = 1; } + my $performances = [{'label' => 'mem.consumed.average', 'instances' => ['']}, + {'label' => 'mem.overhead.average', 'instances' => ['']}]; + if (!defined($self->{no_memory_state})) { + push @{$performances}, {'label' => 'mem.state.latest', 'instances' => ['']}; + } my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, - $result, - [{'label' => 'mem.consumed.average', 'instances' => ['']}, - {'label' => 'mem.overhead.average', 'instances' => ['']}, - {'label' => 'mem.state.latest', 'instances' => ['']}], + $result, $performances, $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); @@ -122,7 +124,10 @@ sub run { # in KB my $mem_used = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"})) * 1024; my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"})) * 1024; - my $mem_state = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"})) * 1024; + my $mem_state; + if (!defined($self->{no_memory_state})) { + $mem_state = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"})) * 1024; + } my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; my $prct_free = 100 - $prct_used; @@ -145,13 +150,16 @@ sub run { $short_msg_append = ', '; } - $output = sprintf("Memory state : %s", $mapping_state{$mem_state}); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $mem_state, threshold => [ { label => 'critical_state', exit_litteral => 'critical' }, { label => 'warning_state', exit_litteral => 'warning' } ]); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; + my $exit2 = 'OK'; + if (!defined($self->{no_memory_state})) { + $output = sprintf("Memory state : %s", $mapping_state{$mem_state}); + $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $mem_state, threshold => [ { label => 'critical_state', exit_litteral => 'critical' }, { label => 'warning_state', exit_litteral => 'warning' } ]); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{manager}->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } } my $prefix_msg = "'$entity_view->{name}'"; @@ -176,11 +184,13 @@ sub run { $self->{manager}->{output}->perfdata_add(label => 'overhead' . $extra_label, unit => 'B', value => $mem_overhead, min => 0); - $self->{manager}->{output}->perfdata_add(label => 'state' . $extra_label, - value => $mem_state, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_state'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_state'), - min => 0, max => 3); + if (!defined($self->{no_memory_state})) { + $self->{manager}->{output}->perfdata_add(label => 'state' . $extra_label, + value => $mem_state, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_state'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_state'), + min => 0, max => 3); + } } } From a5eaa3bc7224ecc360d7776fbc8c9e5e353c37a1 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 17 Nov 2016 17:33:09 +0100 Subject: [PATCH 176/447] + prepare new version --- connectors/vmware/changelog | 3 +++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 1c33022c6..9f5e80595 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2016-11-17 Quentin Garnier - 2.3.1 + * Enhance: Add an option to not check memory ESX state + 2016-08-04 Quentin Garnier - 2.3.0 * Enhance: Add a mode to check connected device (issue #20) * Enhance: Option to use case-insensitive search (issue #14) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 468526601..70b38aebd 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.3.0"; +my $VERSION = "2.3.1"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From b2ccb9efa4f16dd82b43bf639e5db8b3192d9e1b Mon Sep 17 00:00:00 2001 From: rwerquin Date: Thu, 24 Nov 2016 10:30:33 +0100 Subject: [PATCH 177/447] fix typo in doc --- connectors/vmware/doc/fr/exploitation/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/connectors/vmware/doc/fr/exploitation/index.rst b/connectors/vmware/doc/fr/exploitation/index.rst index 2953e8e10..7b4e12208 100644 --- a/connectors/vmware/doc/fr/exploitation/index.rst +++ b/connectors/vmware/doc/fr/exploitation/index.rst @@ -59,7 +59,6 @@ Dans le cas ou il y a plusieurs VirtualCenters, la configuration devient (noter 'default' => {'url' => 'https://vcenter/sdk', 'username' => 'test@test.fr', 'password' => 'xxxx'}, - }, 'other' => {'url' => 'https://other_vcenter/sdk', 'username' => 'test@test.fr', 'password' => 'xxxx'}, From edd843647b778165a05488453cdb5242b2b4872a Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 21 Mar 2017 15:43:32 +0100 Subject: [PATCH 178/447] + add list cluters command --- .../src/centreon/script/centreon_vmware.pm | 1 + .../src/centreon/vmware/cmdlistclusters.pm | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 connectors/vmware/src/centreon/vmware/cmdlistclusters.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 70b38aebd..0f8e70b59 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -74,6 +74,7 @@ my @load_modules = ( 'centreon::vmware::cmdgetmap', 'centreon::vmware::cmdhealthhost', 'centreon::vmware::cmdlimitvm', + 'centreon::vmware::cmdlistclusters', 'centreon::vmware::cmdlistdatacenters', 'centreon::vmware::cmdlistdatastores', 'centreon::vmware::cmdlistnichost', diff --git a/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm b/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm new file mode 100644 index 000000000..9c77d3186 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm @@ -0,0 +1,95 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdlistclusters; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'listclusters'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{cluster}) && $options{arguments}->{cluster} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: cluster cannot be null"); + return 1; + } + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::vmware::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub run { + my $self = shift; + + my $multiple = 0; + my $filters = $self->build_filter(label => 'name', search_option => 'cluster', is_regexp => 'filter'); + my @properties = ('name'); + + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); + return if (!defined($result)); + + if (!defined($self->{disco_show})) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => 'List cluster(s):'); + } + foreach my $cluster (@$result) { + if (defined($self->{disco_show})) { + $self->{manager}->{output}->add_disco_entry(name => $cluster->name); + } else { + $self->{manager}->{output}->output_add(long_msg => sprintf(" %s", + $cluster->name)); + } + } + + if (defined($self->{disco_show})) { + my $stdout; + { + local *STDOUT; + $self->{manager}->{output}->{option_results}->{output_xml} = 1; + open STDOUT, '>', \$stdout; + $self->{manager}->{output}->display_disco_show(); + delete $self->{manager}->{output}->{option_results}->{output_xml}; + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => $stdout); + } + } +} + +1; From aa839c2348143660ed23f2510ec9dda13ad8ccda Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 12 May 2017 17:06:34 +0200 Subject: [PATCH 179/447] + Fix #38 --- connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index 862a13ce2..fe9e7b80b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -156,8 +156,8 @@ sub run { $self->display_verbose(label => 'vmtools not running:', vms => \%not_running); } if (scalar(keys %not_installed) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{tools_notupd2date_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{tools_notupd2date_status}, + !$self->{manager}->{output}->is_status(value => $self->{tools_notinstalled_status}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $self->{tools_notinstalled_status}, short_msg => sprintf('%d VM with VMTools not installed', scalar(keys %not_installed))); $self->display_verbose(label => 'vmtools not installed:', vms => \%not_installed); } From a2ec6c55ab4193d04fbad97eee64f5edc2d5de7f Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 12 May 2017 17:28:26 +0200 Subject: [PATCH 180/447] + Fix #39 --- .../centreon/vmware/cmddatastoresnapshot.pm | 10 +++++++++- .../vmware/src/centreon/vmware/common.pm | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm index 70d1385b2..5b550f14b 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm @@ -111,7 +111,15 @@ sub run { $dsName = $ds_names{$tmp_name}; $self->{manager}->{output}->output_add(long_msg => "Checking datastore '$dsName':"); - my ($snapshots, $msg) = centreon::vmware::common::search_in_datastore($self->{connector}, $browse_ds, '[' . $dsName . ']', [VmSnapshotFileQuery->new()], 1); + my ($snapshots, $msg) = centreon::vmware::common::search_in_datastore( + connector => $self->{connector}, + browse_ds => $browse_ds, + ds_name => '[' . $dsName . ']', + matchPattern => [ "*.vmsn", "*.vmsd", "*-000*.vmdk", "*-000*delta.vmdk" ], + searchCaseInsensitive => 1, + query => [ FileQuery->new()], + return => 1 + ); if (!defined($snapshots)) { $msg =~ s/\n/ /g; if ($msg =~ /NoPermissionFault/i) { diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 53fa6cdff..976374577 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -187,8 +187,7 @@ sub get_view { } sub search_in_datastore { - my $obj_vmware = shift; - my ($ds_browse, $ds_name, $query, $return) = @_; + my (%options) = @_; my $result; my $files = FileQueryFlags->new(fileSize => 1, @@ -196,15 +195,19 @@ sub search_in_datastore { modification => 1, fileOwner => 1 ); - my $hostdb_search_spec = HostDatastoreBrowserSearchSpec->new(details => $files, - query => $query); + my $hostdb_search_spec = HostDatastoreBrowserSearchSpec->new( + details => $files, + searchCaseInsensitive => $options{searchCaseInsensitive}, + matchPattern => $options{matchPattern}, + query => $options{query} + ); eval { - $result = $ds_browse->SearchDatastoreSubFolders(datastorePath=> $ds_name, - searchSpec=>$hostdb_search_spec); + $result = $options{browse_ds}->SearchDatastoreSubFolders(datastorePath => $options{ds_name}, + searchSpec => $hostdb_search_spec); }; if ($@) { - return (undef, $@) if (defined($return) && $return == 1); - vmware_error($obj_vmware, $@); + return (undef, $@) if (defined($options{return}) && $options{return} == 1); + vmware_error($options{connector}, $@); return undef; } return $result; From ce02ce6b118b2a04dad501286b058a56c1f465c9 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 12 May 2017 17:28:55 +0200 Subject: [PATCH 181/447] + prepare new version --- connectors/vmware/changelog | 4 ++++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 9f5e80595..d27f4ec33 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,7 @@ +2017-XX-XX Quentin Garnier - 2.3.2 + * Fix: miscalcultion in datastores-snapshot (issue #39) + * Fix: problem with --tools-notinstalled-status option (issue #38) + 2016-11-17 Quentin Garnier - 2.3.1 * Enhance: Add an option to not check memory ESX state diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 0f8e70b59..aadecd988 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.3.1"; +my $VERSION = "2.3.2"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From 35783b116ac38508b12b48f635b18b66fe303914 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 12 May 2017 18:11:31 +0200 Subject: [PATCH 182/447] + new release --- connectors/vmware/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index d27f4ec33..9a0efd151 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,4 +1,4 @@ -2017-XX-XX Quentin Garnier - 2.3.2 +2017-05-12 Quentin Garnier - 2.3.2 * Fix: miscalcultion in datastores-snapshot (issue #39) * Fix: problem with --tools-notinstalled-status option (issue #38) From aa6c0a538f040ed3a0bc0be3331a2a03aa615689 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 16 May 2017 17:27:10 +0200 Subject: [PATCH 183/447] + Fix #40 --- connectors/vmware/src/centreon/vmware/cmdmemhost.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index df74121dc..f0b1c3597 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -126,7 +126,7 @@ sub run { my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"})) * 1024; my $mem_state; if (!defined($self->{no_memory_state})) { - $mem_state = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"})) * 1024; + $mem_state = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"})); } my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; From 5e51353a4a49b3379e2cf770ee1e06d11b714852 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 16 May 2017 17:28:51 +0200 Subject: [PATCH 184/447] + prepare release --- connectors/vmware/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 9a0efd151..0350cbeb6 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,6 +1,7 @@ -2017-05-12 Quentin Garnier - 2.3.2 +2017-05-16 Quentin Garnier - 2.3.2 * Fix: miscalcultion in datastores-snapshot (issue #39) * Fix: problem with --tools-notinstalled-status option (issue #38) + * Fix: host memory state problem (issue #40) 2016-11-17 Quentin Garnier - 2.3.1 * Enhance: Add an option to not check memory ESX state From 40560537da0c3c557298fdcdf1051ff5bf58f102 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 31 May 2017 14:42:32 +0200 Subject: [PATCH 185/447] version 2.4.0 --- connectors/vmware/changelog | 5 ++++- connectors/vmware/doc/en/installation/index.rst | 12 ++++++------ connectors/vmware/doc/fr/installation/index.rst | 12 ++++++------ .../vmware/src/centreon/script/centreon_vmware.pm | 6 +++--- connectors/vmware/src/centreon/vmware/common.pm | 2 +- connectors/vmware/src/centreon/vmware/connector.pm | 4 ++-- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 0350cbeb6..f51d1786c 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2017-05-31 Quentin Garnier - 2.4.0 + * Enhance: Use ZMQ4 library + 2017-05-16 Quentin Garnier - 2.3.2 * Fix: miscalcultion in datastores-snapshot (issue #39) * Fix: problem with --tools-notinstalled-status option (issue #38) @@ -29,4 +32,4 @@ * Fix: counter 'active' for command 'memory-vm' (issue #6) 2015-09-23 Quentin Garnier - 2.0.0 - * initial release \ No newline at end of file + * initial release diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 6a96e651e..4b94a7115 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -21,7 +21,7 @@ perl-centreon-base 2.6.0 centreon-plugins-base 1.11 ZeroMQ 3.x Perl Date::Parse 1.x -Perl ZMQ::LibZMQ3 1.19 +Perl ZMQ::LibZMQ4 0.01 Perl ZMQ::Constants 1.04 ====================== ===================== @@ -95,13 +95,13 @@ Add the following line in « /etc/apt/sources.list » file: Install « zeromq » dependency: :: - # aptitude install libzmq3-dev gcc - # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-LibZMQ3-1.19.tar.gz - # tar zxf ZMQ-LibZMQ3-1.19.tar.gz && cd ZMQ-LibZMQ3-1.19 + # aptitude install libzmq4-dev gcc + # wget https://github.com/lestrrat/p5-ZMQ/archive/master.zip + # unzip master.zip + # cd p5-ZMQ-master/ZMQ-LibZMQ4/ # perl Makefile.PL # make && make install - # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-Constants-1.04.tar.gz - # tar zxf ZMQ-Constants-1.04.tar.gz && cd ZMQ-Constants-1.04 + # cd p5-ZMQ-master/ZMQ-Constants/ # perl Makefile.PL # make && make install diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index 113559dfb..38ac826f2 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -21,7 +21,7 @@ perl-centreon-base 2.5.0 centreon-plugins-base 1.10 ZeroMQ 3.x Perl Date::Parse 1.x -Perl ZMQ::LibZMQ3 1.19 +Perl ZMQ::LibZMQ4 0.01 Perl ZMQ::Constants 1.04 ====================== ===================== @@ -95,13 +95,13 @@ Ajouter la ligne suivante dans le fichier « /etc/apt/sources.list »: Installer la dépendance « zeromq »: :: - # aptitude install libzmq3-dev gcc - # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-LibZMQ3-1.19.tar.gz - # tar zxf ZMQ-LibZMQ3-1.19.tar.gz && cd ZMQ-LibZMQ3-1.19 + # aptitude install libzmq4-dev gcc + # wget https://github.com/lestrrat/p5-ZMQ/archive/master.zip + # unzip master.zip + # cd p5-ZMQ-master/ZMQ-LibZMQ4/ # perl Makefile.PL # make && make install - # wget https://cpan.metacpan.org/authors/id/D/DM/DMAKI/ZMQ-Constants-1.04.tar.gz - # tar zxf ZMQ-Constants-1.04.tar.gz && cd ZMQ-Constants-1.04 + # cd p5-ZMQ-master/ZMQ-Constants/ # perl Makefile.PL # make && make install diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index aadecd988..637ba27f5 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -23,7 +23,7 @@ use strict; use warnings; use VMware::VIRuntime; use VMware::VILib; -use ZMQ::LibZMQ3; +use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); use File::Basename; use Digest::MD5 qw(md5_hex); @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.3.2"; +my $VERSION = "2.4.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( @@ -594,4 +594,4 @@ sub run { 1; -__END__ \ No newline at end of file +__END__ diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 976374577..ce58c75de 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -23,7 +23,7 @@ use strict; use Data::Dumper; use VMware::VIRuntime; use VMware::VILib; -use ZMQ::LibZMQ3; +use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); use centreon::plugins::options; use centreon::plugins::output; diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index c1efab7e2..56e7c1b5f 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -22,7 +22,7 @@ use strict; use VMware::VIRuntime; use VMware::VILib; use JSON; -use ZMQ::LibZMQ3; +use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); use File::Basename; use POSIX ":sys_wait_h"; @@ -323,4 +323,4 @@ sub run { 1; -__END__ \ No newline at end of file +__END__ From 253abc658a4dacf13c5276d1a16ebf987117a1c9 Mon Sep 17 00:00:00 2001 From: MaxCentreon <31695868+MaxCentreon@users.noreply.github.com> Date: Thu, 9 Nov 2017 13:45:15 +0100 Subject: [PATCH 186/447] Update index.rst --- connectors/vmware/doc/en/installation/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 4b94a7115..2732b7ee9 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -243,7 +243,7 @@ Install the client and dependency: # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ # cp centreon_plugins.pl /usr/lib/nagios/plugins/ -Centreon-vmware Installation - centos/rhel 6 systems +Centreon-vmware Installation - centos/rhel 6 systems & centos 7 ==================================================== SDK Perl VMWare Installation @@ -287,12 +287,12 @@ centreon-vmware Installation with rpm Install the connector: :: - # yum install ces-plugins-Virtualization-VMWare-daemon + # yum install centreon-plugin-Virtualization-VMWare-daemon Install the client: :: - # yum install ces-plugins-Virtualization-VMWare-client + # yum install centreon-plugin-Virtualization-VMWare-client centreon-vmware Installation with source ```````````````````````````````````````` From 1fea60e9ae3d9be5a14c8a64acfa800b4bbd816f Mon Sep 17 00:00:00 2001 From: Colin GAGNAIRE Date: Fri, 29 Dec 2017 14:05:36 +0100 Subject: [PATCH 187/447] improve cmdnethost --- .../vmware/src/centreon/vmware/cmdnethost.pm | 70 ++++++++++++++++--- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index 5a16e2244..53fe72b5c 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -59,7 +59,8 @@ sub checkArgs { short_msg => "Argument error: wrong value for link down status '" . $options{arguments}->{link_down_status} . "'"); return 1; } - foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out')) { + foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out', + 'warning_dropped_in', 'critical_dropped_in', 'warning_dropped_out', 'critical_dropped_out')) { if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); @@ -77,7 +78,8 @@ sub initArgs { } $self->{manager} = centreon::vmware::common::init_response(); $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out')) { + foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out', + 'warning_dropped_in', 'critical_dropped_in', 'warning_dropped_out', 'critical_dropped_out')) { $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); } } @@ -170,9 +172,9 @@ sub run { } if (scalar(@$instances) == 0 && ($multiple == 0 || ($multiple == 1 && !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1)))) { - $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, - short_msg => sprintf("%s Link(s) '%s' is(are) down", - $entity_view->{name}, join("','", keys %{$pnic_def_down->{$entity_view->{mo_ref}->{value}}}))); + $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, + short_msg => sprintf("%s Link(s) '%s' is/are down", + $entity_view->{name}, join("', '", keys %{$pnic_def_down->{$entity_view->{mo_ref}->{value}}}))); next; } @@ -180,7 +182,11 @@ sub run { entity => $entity_view, metrics => [ {label => 'net.received.average', instances => $instances}, - {label => 'net.transmitted.average', instances => $instances} + {label => 'net.transmitted.average', instances => $instances}, + {label => 'net.droppedRx.summation', instances => $instances}, + {label => 'net.droppedTx.summation', instances => $instances}, + {label => 'net.packetsRx.summation', instances => $instances}, + {label => 'net.packetsTx.summation', instances => $instances} ] }; } @@ -200,14 +206,18 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; if (scalar(keys %{$pnic_def_down->{$entity_value}}) > 0 && (($multiple == 0 && $number_nic == 1) || !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1))) { + ($number_nic == 1) ? my $be = "is" : my $be = "are"; $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, - short_msg => sprintf("%s Link(s) '%s' is(are) down", - $entity_view->{name}, join("','", keys %{$pnic_def_down->{$entity_value}}))); + short_msg => sprintf("%s Link(s) '%s' %s down", + $entity_view->{name}, join("', '", keys %{$pnic_def_down->{$entity_value}}), $be)); } my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits; foreach (sort keys %{$pnic_def_up->{$entity_value}}) { + my $interface = sprintf("Interface '%s'", $_); + my $output = ''; + # KBps my $traffic_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_})) * 1024 * 8; my $traffic_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_})) * 1024 * 8; @@ -223,13 +233,13 @@ sub run { my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); push @exits, $exit; - my $output = sprintf("Interface '%s' Traffic In : %s/s (%.2f %%), Out : %s/s (%.2f %%) ", $_, + $output = sprintf("Traffic In : %s/s (%.2f %%), Out : %s/s (%.2f %%)", $in_value . $in_unit, $in_prct, $out_value . $out_unit, $out_prct); - $long_msg .= $long_msg_append . $output; + $long_msg .= $long_msg_append . $interface . " " . $output; $long_msg_append = ', '; if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0 && $number_nic == 1)) { - $short_msg .= $short_msg_append . $output; + $short_msg .= $short_msg_append . $interface . " " . $output; $short_msg_append = ', '; } @@ -246,6 +256,44 @@ sub run { warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-out', total => $interface_speed), critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-out', total => $interface_speed), min => 0, max => $interface_speed); + + # Packets dropped + my $packets_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.packetsRx.summation'}->{key} . ":" . $_})); + my $packets_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.packetsTx.summation'}->{key} . ":" . $_})); + my $dropped_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedRx.summation'}->{key} . ":" . $_})); + my $dropped_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedTx.summation'}->{key} . ":" . $_})); + my $dropped_in_prct = $dropped_in * 100 / $packets_in; + my $dropped_out_prct = $dropped_out * 100 / $packets_out; + + my $exit3 = $self->{manager}->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical_dropped_in', exit_litteral => 'critical' }, { label => 'warning_dropped_in', exit_litteral => 'warning' } ]); + my $exit4 = $self->{manager}->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical_dropped_out', exit_litteral => 'critical' }, { label => 'warning_dropped_out', exit_litteral => 'warning' } ]); + + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit3, $exit4 ]); + push @exits, $exit; + + $output = sprintf("Packets In Dropped : %.2f %% (%d/%d packets), Packets Out Dropped : %.2f %% (%d/%d packets)", + $dropped_in_prct, $dropped_in, $packets_in, + $dropped_out_prct, $dropped_out, $packets_out); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0 && $number_nic == 1)) { + $short_msg .= $short_msg_append . $interface . " " . $output; + $short_msg_append = ', '; + } + + $extra_label = ''; + $extra_label .= '_' . $_ if ($number_nic > 1); + $extra_label .= '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'packets_dropped_in' . $extra_label, unit => '%', + value => sprintf("%.2f", $dropped_in_prct), + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-dropped-in'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-dropped-in'), + min => 0, max => 100); + $self->{manager}->{output}->perfdata_add(label => 'packets_dropped_out' . $extra_label, unit => '%', + value => sprintf("%.2f", $dropped_out_prct), + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-dropped-out'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-dropped-out'), + min => 0, max => 100); } $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' $long_msg"); From 346653afbfecdf352c44d551dcf635e955596c65 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 2 Jan 2018 10:36:17 +0100 Subject: [PATCH 188/447] Fix #54 --- connectors/vmware/src/centreon/vmware/cmdmemhost.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index f0b1c3597..4ef09179b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -126,7 +126,7 @@ sub run { my $mem_overhead = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.overhead.average'}->{'key'} . ":"})) * 1024; my $mem_state; if (!defined($self->{no_memory_state})) { - $mem_state = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"})); + $mem_state = centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"}); } my $mem_free = $memory_size - $mem_used; my $prct_used = $mem_used * 100 / $memory_size; From 602bef171ba73836bbbda228426c59b5f8a40ead Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 2 Jan 2018 14:33:19 +0100 Subject: [PATCH 189/447] Fix #55 --- connectors/vmware/src/centreon/vmware/common.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index ce58c75de..03871dd51 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -399,7 +399,13 @@ sub generic_performance_values_historic { } }; if ($@) { - $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); + if ($@ =~ /querySpec.interval.*InvalidArgumentFault/msi) { + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Interval '%s' is surely not supported for the managed entity (caller: %s)", + $interval, join('--', caller))); + } else { + $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); + } return undef; } return \%results; From 3676ac499b286ddcd8cbd2dfa0d65c82b6b3ceec Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 2 Jan 2018 15:29:19 +0100 Subject: [PATCH 190/447] remove host --- connectors/vmware/src/centreon/vmware/cmdnethost.pm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index 53fe72b5c..8f5d64382 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -272,8 +272,8 @@ sub run { push @exits, $exit; $output = sprintf("Packets In Dropped : %.2f %% (%d/%d packets), Packets Out Dropped : %.2f %% (%d/%d packets)", - $dropped_in_prct, $dropped_in, $packets_in, - $dropped_out_prct, $dropped_out, $packets_out); + $dropped_in_prct, $dropped_in, $packets_in, + $dropped_out_prct, $dropped_out, $packets_out); $long_msg .= $long_msg_append . $output; $long_msg_append = ', '; if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0 && $number_nic == 1)) { @@ -281,9 +281,6 @@ sub run { $short_msg_append = ', '; } - $extra_label = ''; - $extra_label .= '_' . $_ if ($number_nic > 1); - $extra_label .= '_' . $entity_view->{name} if ($multiple == 1); $self->{manager}->{output}->perfdata_add(label => 'packets_dropped_in' . $extra_label, unit => '%', value => sprintf("%.2f", $dropped_in_prct), warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-dropped-in'), From 3d34e94f3a305e3646851df12984cdff9e5f1726 Mon Sep 17 00:00:00 2001 From: Andrea Cervesato Date: Mon, 14 May 2018 10:53:38 +0200 Subject: [PATCH 191/447] fix division by 0 (#64) --- connectors/vmware/src/centreon/vmware/cmdnethost.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index 8f5d64382..429a73403 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -262,8 +262,8 @@ sub run { my $packets_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.packetsTx.summation'}->{key} . ":" . $_})); my $dropped_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedRx.summation'}->{key} . ":" . $_})); my $dropped_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedTx.summation'}->{key} . ":" . $_})); - my $dropped_in_prct = $dropped_in * 100 / $packets_in; - my $dropped_out_prct = $dropped_out * 100 / $packets_out; + my $dropped_in_prct = ($packets_in > 0) ? $dropped_in * 100 / $packets_in : 0; + my $dropped_out_prct = ($packets_out > 0) ? $dropped_out * 100 / $packets_out : 0; my $exit3 = $self->{manager}->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical_dropped_in', exit_litteral => 'critical' }, { label => 'warning_dropped_in', exit_litteral => 'warning' } ]); my $exit4 = $self->{manager}->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical_dropped_out', exit_litteral => 'critical' }, { label => 'warning_dropped_out', exit_litteral => 'warning' } ]); From bf563ab91f236b8bb002a809bd79619a4cb78783 Mon Sep 17 00:00:00 2001 From: pkriko <32265250+pkriko@users.noreply.github.com> Date: Mon, 11 Jun 2018 10:30:18 +0200 Subject: [PATCH 192/447] Update centreon_vmware-systemd Change the user to centreon. Is this way, the log centreon_vmware.log will have centreon as owner and the logrotate will work. --- connectors/vmware/packaging/redhat/centreon_vmware-systemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/packaging/redhat/centreon_vmware-systemd b/connectors/vmware/packaging/redhat/centreon_vmware-systemd index 0ed2bf8fe..c0660a430 100644 --- a/connectors/vmware/packaging/redhat/centreon_vmware-systemd +++ b/connectors/vmware/packaging/redhat/centreon_vmware-systemd @@ -21,7 +21,7 @@ Description=Centreon VMWare [Service] ExecStart=/usr/bin/perl /usr/bin/centreon_vmware.pl --logfile=/var/log/centreon/centreon_vmware.log --severity=error Type=simple -User=root +User=centreon [Install] WantedBy=multi-user.target From 5160ff87053130c29bef41cc2743c532856bab18 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Fri, 25 Jan 2019 16:44:25 +0100 Subject: [PATCH 193/447] Add discovery mode (#73) * add discovery mode * add discovery mode --- .../src/centreon/script/centreon_vmware.pm | 1 + .../src/centreon/vmware/cmddiscovery.pm | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 connectors/vmware/src/centreon/vmware/cmddiscovery.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 637ba27f5..58b528195 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -71,6 +71,7 @@ my @load_modules = ( 'centreon::vmware::cmddatastorevm', 'centreon::vmware::cmddatastoreusage', 'centreon::vmware::cmddevicevm', + 'centreon::vmware::cmddiscovery', 'centreon::vmware::cmdgetmap', 'centreon::vmware::cmdhealthhost', 'centreon::vmware::cmdlimitvm', diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm new file mode 100644 index 000000000..a1f4ee63f --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -0,0 +1,163 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmddiscovery; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'discovery'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + return 0; +} + +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::vmware::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; +} + +sub run { + my $self = shift; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); + my @properties = ('name', 'hostFolder'); + + my $datacenters = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => $filters); + return if (!defined($datacenters)); + + foreach my $datacenter (@{$datacenters}) { + my @properties = ('childType', 'childEntity'); + + my @array; + if (defined $datacenter->hostFolder) { + push @array, $datacenter->hostFolder; + } + + my $childs = centreon::vmware::common::get_views($self->{connector}, \@array, \@properties); + next if (!defined($childs)); + + foreach my $child (@{$childs}) { + my %types = map { $_ => 1 } @{$child->childType}; + next if (!defined($types{ComputeResource})); + my @properties = ('name', 'host'); + + my $clusters = centreon::vmware::common::get_views($self->{connector}, \@{$child->childEntity}, \@properties); + next if (!defined($clusters)); + + foreach my $cluster (@{$clusters}) { + my @properties = ('name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', + 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', + 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState'); + + my $esxs = centreon::vmware::common::get_views($self->{connector}, \@{$cluster->host}, \@properties); + next if (!defined($esxs)); + + foreach my $esx (@{$esxs}) { + my %esx; + + $esx{type} = "esx"; + $esx{name} = $esx->name; + $esx{os} = $esx->{'config.product.productLineId'} . ' ' . $esx->{'config.product.version'}; + $esx{hardware} = $esx->{'hardware.systemInfo.vendor'} . ' ' . $esx->{'hardware.systemInfo.model'}; + $esx{power_state} = $esx->{'runtime.powerState'}->val; + $esx{connection_state} = $esx->{'runtime.connectionState'}->val; + $esx{maintenance} = $esx->{'runtime.inMaintenanceMode'}; + $esx{datacenter} = $datacenter->name; + $esx{cluster} = $cluster->name; + + foreach my $nic (@{$esx->{'config.virtualNicManagerInfo.netConfig'}}) { + my %lookup = map { $_->{'key'} => $_->{'spec'}->{'ip'}->{'ipAddress'} } @{$nic->{'candidateVnic'}}; + foreach my $vnic (@{$nic->{'selectedVnic'}}) { + push @{$esx{'ip_' . $nic->{'nicType'}}}, $lookup{$vnic}; + } + } + + push @disco_data, \%esx; + + @properties = ('config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', + 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState'); + + my $vms = centreon::vmware::common::get_views($self->{connector}, \@{$esx->vm}, \@properties); + next if (!defined($vms)); + + foreach my $vm (@{$vms}) { + my %vm; + + $vm{type} = "vm"; + $vm{name} = $vm->{'config.name'}; + $vm{annotation} = $vm->{'config.annotation'}; + $vm{os} = $vm->{'config.guestId'}; + $vm{hardware} = $vm->{'config.version'}; + $vm{guest_name} = $vm->{'guest.hostName'}; + $vm{guest_ip} = $vm->{'guest.ipAddress'}; + $vm{guest_state} = $vm->{'guest.guestState'}; + $vm{power_state} = $vm->{'runtime.powerState'}->val; + $vm{datacenter} = $datacenter->name; + $vm{cluster} = $cluster->name; + $vm{esx} = $esx->name; + + push @disco_data, \%vm; + } + } + } + } + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + $encoded_data = encode_json($disco_stats); + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{manager}->{output}->output_add(short_msg => $encoded_data); + $self->{manager}->{output}->display(nolabel => 1, force_ignore_perfdata => 1); +} + +1; From 6c35fdb8540990fb677af8f8d360c8582b42ca18 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 30 Jan 2019 18:10:11 +0100 Subject: [PATCH 194/447] WIP: new version centreon-vmware 3.0.0 --- .../src/centreon/script/centreon_vmware.pm | 33 ++- .../src/centreon/vmware/cmdalarmdatacenter.pm | 109 +-------- .../src/centreon/vmware/cmdalarmhost.pm | 106 +-------- .../vmware/src/centreon/vmware/cmdbase.pm | 10 + .../src/centreon/vmware/cmdcountvmhost.pm | 81 +------ .../vmware/src/centreon/vmware/cmdcpuhost.pm | 87 ++----- .../vmware/src/centreon/vmware/cmdcpuvm.pm | 124 ++-------- .../centreon/vmware/cmddatastorecountvm.pm | 79 +------ .../src/centreon/vmware/cmddatastorehost.pm | 90 ++----- .../src/centreon/vmware/cmddatastoreio.pm | 86 +------ .../src/centreon/vmware/cmddatastoreiops.pm | 124 +++------- .../centreon/vmware/cmddatastoresnapshot.pm | 86 ++----- .../src/centreon/vmware/cmddatastoreusage.pm | 130 ++--------- .../src/centreon/vmware/cmddatastorevm.pm | 130 +++-------- .../vmware/src/centreon/vmware/cmdmemhost.pm | 114 ++------- .../vmware/src/centreon/vmware/cmdnethost.pm | 220 +++--------------- .../vmware/src/centreon/vmware/common.pm | 107 ++++----- .../vmware/src/centreon/vmware/connector.pm | 12 +- 18 files changed, 320 insertions(+), 1408 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 58b528195..132d636a5 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -331,8 +331,7 @@ sub waiting_ready { } if ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "connector still not ready."); + centreon::vmware::common::set_response(code => -1, short_message => "connector still not ready."); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return 0; } @@ -345,8 +344,7 @@ sub request_dynamic { if (!defined($options{result}->{vsphere_username}) || $options{result}->{vsphere_username} eq '' || !defined($options{result}->{vsphere_password}) || $options{result}->{vsphere_password} eq '') { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Please set vsphere username or password"); + centreon::vmware::common::set_response(code => -1, short_message => "Please set vsphere username or password"); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } @@ -386,20 +384,17 @@ sub request { $result = JSON->new->utf8->decode($options{data}); }; if ($@) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot decode json result: $@"); + centreon::vmware::common::set_response(code => 1, short_message => "Cannot decode json result: $@"); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } if ($result->{command} eq 'stats') { - centreon::vmware::common::stats_info(manager => $options{manager}, - counters => $self->{counter_stats}); + centreon::vmware::common::stats_info(counters => $self->{counter_stats}); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } if (!defined($self->{modules_registry}->{$result->{command}})) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Unknown method name '$result->{command}'"); + centreon::vmware::common::set_response(code => 1, short_message => "Unknown method name '$result->{command}'"); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } @@ -416,8 +411,7 @@ sub request { } if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$result->{container}})) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Unknown container name '$result->{container}'"); + centreon::vmware::common::set_response(code => 1, short_message => "Unknown container name '$result->{container}'"); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } @@ -448,12 +442,12 @@ sub repserver { $self->{logger}->writeLogError("Cannot decode JSON: $@ (options{data}"); return ; } - - $result->{plugin}->{name} =~ /^client-(.*)$/; + + $result->{identity} =~ /^client-(.*)$/; my $identity = 'client-' . pack('H*', $1); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, - identity => $identity, stdout => $options{data}); + identity => $identity, force_response => $options{data}); } sub router_event { @@ -469,16 +463,15 @@ sub router_event { my $data = zmq_msg_data($msg); zmq_msg_close($msg); - my $manager = centreon::vmware::common::init_response(); + centreon::vmware::common::init_response(); if ($centreon_vmware->{stop} != 0) { # We quit so we say we're leaving ;) - $manager->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Daemon is restarting/stopping...'); + centreon::vmware::common::set_response(code => -1, short_message => 'Daemon is restarting/stopping...'); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $identity); } elsif ($data =~ /^REQCLIENT\s+(.*)$/msi) { - $centreon_vmware->request(identity => $identity, data => $1, manager => $manager); + $centreon_vmware->request(identity => $identity, data => $1); } elsif ($data =~ /^RESPSERVER2\s+(.*)$/msi) { - $centreon_vmware->repserver(data => $1, manager => $manager); + $centreon_vmware->repserver(data => $1); } elsif ($data =~ /^READY/msi) { $identity =~ /server-(.*)/; $centreon_vmware->{centreon_vmware_config}->{vsphere_server}->{$1}->{ready} = 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm index d660ad6b6..e9c779dc7 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmdatacenter.pm @@ -23,8 +23,6 @@ use base qw(centreon::vmware::cmdbase); use strict; use warnings; use centreon::vmware::common; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); sub new { my ($class, %options) = @_; @@ -40,123 +38,40 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datacenter}) && $options{arguments}->{datacenter} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datacenter cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datacenter cannot be null"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); -} - sub run { my $self = shift; - - if (defined($self->{memory})) { - $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); - $self->{statefile_cache}->read(statefile_dir => $self->{connector}->{retention_dir}, - statefile => "cache_vmware_connector_" . $self->{connector}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{datacenter}) ? md5_hex($self->{datacenter}) : md5_hex('.*')), - statefile_suffix => '', - no_quit => 1); - return if ($self->{statefile_cache}->error() == 1); - } - - my $multiple = 0; - if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{connector}->{module_date_parse_loaded} == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Need to install Date::Parse CPAN Module"); - return ; - } my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); my @properties = ('name', 'triggeredAlarmState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("No current alarms on datacenter(s)")); - - my $total_alarms = { red => 0, yellow => 0 }; - my $dc_alarms = {}; - my $new_datas = {}; + my $data = {}; foreach my $datacenter_view (@$result) { - $dc_alarms->{$datacenter_view->name} = { red => 0, yellow => 0, alarms => {} }; + $data->{$datacenter_view->{mo_ref}->{value}} = { name => $datacenter_view->name, red => 0, yellow => 0, alarms => {} }; next if (!defined($datacenter_view->triggeredAlarmState)); foreach (@{$datacenter_view->triggeredAlarmState}) { next if ($_->overallStatus->val !~ /(red|yellow)/i); - if (defined($self->{filter_time}) && $self->{filter_time} ne '') { - my $time_sec = Date::Parse::str2time($_->time); - next if (time() - $time_sec > $self->{filter_time}); - } - $new_datas->{$_->key} = 1; - next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); - + my $entity = centreon::vmware::common::get_view($self->{connector}, $_->entity, ['name']); my $alarm = centreon::vmware::common::get_view($self->{connector}, $_->alarm, ['info']); - $dc_alarms->{$datacenter_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, entity_name => $entity->name, - time => $_->time, name => $alarm->info->name, - description => $alarm->info->description, - status => $_->overallStatus->val}; - $dc_alarms->{$datacenter_view->name}->{$_->overallStatus->val}++; - $total_alarms->{$_->overallStatus->val}++; + $data->{$datacenter_view->{mo_ref}->{value}}->{alarms}->{$_->key} = { type => $_->entity->type, entity_name => $entity->name, + time => $_->time, name => $alarm->info->name, + description => $alarm->info->description, + status => $_->overallStatus->val + }; + $data->{$datacenter_view->{mo_ref}->{value}}->{$_->overallStatus->val}++; } - } - - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{yellow}, - threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{yellow})); - } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{red}, threshold => [ { label => 'critical', exit_litteral => 'critical' } ]); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{red})); } - - foreach my $dc_name (keys %{$dc_alarms}) { - $self->{manager}->{output}->output_add(long_msg => sprintf("Checking datacenter %s", $dc_name)); - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", - $dc_alarms->{$dc_name}->{yellow}, $dc_alarms->{$dc_name}->{red})); - foreach my $alert (keys %{$dc_alarms->{$dc_name}->{alarms}}) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s/%s", - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{status}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{type}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{entity_name}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{time}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{name}, - $dc_alarms->{$dc_name}->{alarms}->{$alert}->{description} - )); - } - - my $extra_label = ''; - $extra_label = '_' . $dc_name if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'alarm_warning' . $extra_label, - value => $dc_alarms->{$dc_name}->{yellow}, - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'alarm_critical' . $extra_label, - value => $dc_alarms->{$dc_name}->{red}, - min => 0); - } - - if (defined($self->{memory})) { - $self->{statefile_cache}->write(data => $new_datas); - } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm index 92b6f106d..23588f642 100644 --- a/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdalarmhost.pm @@ -23,8 +23,6 @@ use base qw(centreon::vmware::cmdbase); use strict; use warnings; use centreon::vmware::common; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); sub new { my ($class, %options) = @_; @@ -40,123 +38,41 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); -} - sub run { my $self = shift; - if (defined($self->{memory})) { - $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); - $self->{statefile_cache}->read(statefile_dir => $self->{connector}->{retention_dir}, - statefile => "cache_vmware_connector_" . $self->{connector}->{whoaim} . "_" . (defined($self->{esx_hostname}) ? md5_hex($self->{esx_hostname}) : md5_hex('.*')), - statefile_suffix => '', - no_quit => 1); - return if ($self->{statefile_cache}->error() == 1); - } - - my $multiple = 0; - - if (defined($self->{filter_time}) && $self->{filter_time} ne '' && $self->{connector}->{module_date_parse_loaded} == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Need to install Date::Parse CPAN Module"); - return ; - } - my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'triggeredAlarmState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("No current alarms on host(s)")); - - my $total_alarms = { red => 0, yellow => 0 }; - my $host_alarms = {}; - my $new_datas = {}; + my $data = {}; foreach my $host_view (@$result) { - $host_alarms->{$host_view->name} = { red => 0, yellow => 0, alarms => {} }; + $data->{$host_view->{mo_ref}->{value}} = { name => $host_view->name, red => 0, yellow => 0, alarms => {} }; next if (!defined($host_view->triggeredAlarmState)); foreach(@{$host_view->triggeredAlarmState}) { next if ($_->overallStatus->val !~ /(red|yellow)/i); - if (defined($self->{filter_time}) && $self->{filter_time} ne '') { - my $time_sec = Date::Parse::str2time($_->time); - next if (time() - $time_sec > $self->{filter_time}); - } - $new_datas->{$_->key} = 1; - next if (defined($self->{memory}) && defined($self->{statefile_cache}->get(name => $_->key))); my $entity = centreon::vmware::common::get_view($self->{connector}, $_->entity, ['name']); my $alarm = centreon::vmware::common::get_view($self->{connector}, $_->alarm, ['info']); - $host_alarms->{$host_view->name}->{alarms}->{$_->key} = { type => $_->entity->type, entity_name => $entity->name, - time => $_->time, name => $alarm->info->name, - description => $alarm->info->description, - status => $_->overallStatus->val}; - $host_alarms->{$host_view->name}->{$_->overallStatus->val}++; - $total_alarms->{$_->overallStatus->val}++; + $data->{$host_view->{mo_ref}->{value}}->{alarms}->{$_->key} = { + type => $_->entity->type, entity_name => $entity->name, + time => $_->time, name => $alarm->info->name, + description => $alarm->info->description, + status => $_->overallStatus->val + }; + $data->{$host_view->{mo_ref}->{value}}->{$_->overallStatus->val}++; } } - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{yellow}, - threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{yellow})); - } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_alarms->{red}, threshold => [ { label => 'critical', exit_litteral => 'critical' } ]); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s alarm(s) found(s)", $total_alarms->{red})); - } - - foreach my $host_name (keys %{$host_alarms}) { - $self->{manager}->{output}->output_add(long_msg => sprintf("Checking host %s", $host_name)); - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s warn alarm(s) found(s) - %s critical alarm(s) found(s)", - $host_alarms->{$host_name}->{yellow}, $host_alarms->{$host_name}->{red})); - foreach my $alert (keys %{$host_alarms->{$host_name}->{alarms}}) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" [%s] [%s] [%s] [%s] %s/%s", - $host_alarms->{$host_name}->{alarms}->{$alert}->{status}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{type}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{entity_name}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{time}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{name}, - $host_alarms->{$host_name}->{alarms}->{$alert}->{description} - )); - } - - my $extra_label = ''; - $extra_label = '_' . $host_name if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'alarm_warning' . $extra_label, - value => $host_alarms->{$host_name}->{yellow}, - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'alarm_critical' . $extra_label, - value => $host_alarms->{$host_name}->{red}, - min => 0); - } - - if (defined($self->{memory})) { - $self->{statefile_cache}->write(data => $new_datas); - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index b9021df23..2633d8f5d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -20,6 +20,7 @@ package centreon::vmware::cmdbase; use strict; use warnings; +use centreon::vmware::common; my %handlers = (ALRM => {}); @@ -67,6 +68,15 @@ sub set_connector { alarm(300); } +sub initArgs { + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + centreon::vmware::common::init_response(identity => $options{arguments}->{identity}); +} + sub build_filter { my ($self, %options) = @_; diff --git a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm index 7262f48f7..dedd1b313 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm @@ -38,52 +38,21 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'vm', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } - + #return if (centreon::vmware::common::host_state($self->{connector}, $self->{lhost}, # $$result[0]->{'runtime.connectionState'}->val) == 0); @@ -97,19 +66,11 @@ sub run { my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All ESX Hosts are ok")); - } - - foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + my $data = {}; + foreach my $entity_view (@$result) { + $data->{$entity_view->{name}} = { state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + my %vm_states = (poweredon => 0, poweredoff => 0, suspended => 0); if (defined($entity_view->vm)) { foreach my $vm_host (@{$entity_view->vm}) { @@ -123,30 +84,10 @@ sub run { } } - foreach my $labels ((['poweredon', 'warning_on', 'critical_on'], - ['poweredoff', 'warning_off', 'critical_off'], - ['suspended', 'warning_suspended', 'critical_suspended'])) { - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $vm_states{$labels->[0]}, - threshold => [ { label => $labels->[2], exit_litteral => 'critical' }, - { label => $labels->[1], exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{name}, - $vm_states{$labels->[0]}, - $labels->[0])); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{name}, - $vm_states{$labels->[0]}, - $labels->[0])); - } - - $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, - value => $vm_states{$labels->[0]}, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), - min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); - } + $data->{$entity_view->{name}} = { %{$data->{$entity_view->{name}}}, %vm_states }; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index 01508faec..31c60739f 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -38,59 +38,26 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.connectionState', 'summary.hardware.numCpuCores', 'summary.hardware.cpuMhz'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } my @instances = ('*'); my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, @@ -103,42 +70,22 @@ sub run { my $interval_min = centreon::vmware::common::get_interval_min(speriod => $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}); - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Total Average CPU usages are ok")); - } + + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"} * 0.01)); my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"})); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, - threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", - $entity_view->{name}, $total_cpu_average, $interval_min)); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", - $entity_view->{name}, $total_cpu_average, $interval_min)); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'cpu_total' . $extra_label, unit => '%', - value => $total_cpu_average, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, max => 100); - $self->{manager}->{output}->perfdata_add(label => 'cpu_total_MHz' . $extra_label, unit => 'MHz', - value => $total_cpu_mhz_average, - min => 0, max => $entity_view->{'summary.hardware.numCpuCores'} * $entity_view->{'summary.hardware.cpuMhz'}); + $data->{$entity_value}->{'interval_min'} = $interval_min; + $data->{$entity_value}->{'cpu.usage.average'} = $total_cpu_average; + $data->{$entity_value}->{'cpu.usagemhz.average'} = $total_cpu_mhz_average; + $data->{$entity_value}->{'numCpuCores'} = $entity_view->{'summary.hardware.numCpuCores'}; + $data->{$entity_value}->{'cpuMhz'} = $entity_view->{'summary.hardware.cpuMhz'}; + $data->{$entity_value}->{'cpu'} = {}; foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; @@ -147,12 +94,12 @@ sub run { $cia <=> $cib} keys %{$values->{$entity_value}}) { my ($counter_id, $instance) = split /:/, $id; if ($instance ne "") { - $self->{manager}->{output}->perfdata_add(label => 'cpu' . $instance . $extra_label, unit => '%', - value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}) * 0.01), - min => 0, max => 100); + $data->{$entity_value}->{cpu}->{$instance} = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id}) * 0.01); } } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 7f9161121..90dfdf213 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -38,55 +38,21 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{nopoweredon_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); - return 1; - } - foreach my $label (('warning_usagemhz', 'critical_usagemhz', 'warning_usage', 'critical_usage', 'warning_ready', 'critical_ready')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_usagemhz', 'critical_usagemhz', 'warning_usage', 'critical_usage', 'warning_ready', 'critical_ready')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -110,78 +76,36 @@ sub run { skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All cpu usages are ok")); - } - my $interval_sec = $self->{connector}->{perfcounter_speriod}; if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { $interval_sec = $self->{sampling_period}; } my $interval_min = centreon::vmware::common::get_interval_min(speriod => $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}); + + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - power => $entity_view->{'runtime.powerState'}->val, - status => $self->{disconnect_status}, - powerstatus => $self->{nopoweredon_status}, - multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"} * 0.01)); my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"})); my $total_cpu_ready = centreon::vmware::common::simplify_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.ready.summation'}->{'key'} . ":"} / ($interval_sec * 1000) * 100); - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - foreach my $entry (({ value => $total_cpu_average, label => 'usage', output => 'Total Average CPU usage %s %%', - perf_label => 'cpu_total', perf_min => 0, perf_max => 100, perf_unit => '%' }, - { value => $total_cpu_mhz_average, label => 'usagemhz', output => 'Total Average CPU %s Mhz', - perf_label => 'cpu_total_MHz', perf_min => 0, perf_unit => 'MHz'}, - { value => $total_cpu_ready, label => 'ready', output => 'CPU ready %s %%', - perf_label => 'cpu_ready', perf_min => 0, perf_unit => '%' })) { - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $entry->{value}, threshold => [ { label => 'critical_' . $entry->{label}, exit_litteral => 'critical' }, { label => 'warning_' . $entry->{label}, exit_litteral => 'warning' } ]); - push @exits, $exit; - - my $output = sprintf($entry->{output}, $entry->{value}); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $self->{manager}->{output}->perfdata_add(label => $entry->{perf_label} . $extra_label, unit => $entry->{perf_unit}, - value => $entry->{value}, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_' . $entry->{label}), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_' . $entry->{label}), - min => $entry->{perf_min}, max => $entry->{perf_max}); - } - - $long_msg .= ' on last ' . $interval_min . ' min'; - my $prefix_msg = "'$entity_view->{name}'"; - if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && - $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; - } - - $self->{manager}->{output}->output_add(long_msg => "$prefix_msg $long_msg"); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => "$prefix_msg $short_msg" - ); - } - if ($multiple == 0) { - $self->{manager}->{output}->output_add(short_msg => "$prefix_msg $long_msg"); - } + $data->{$entity_value}->{'cpu.usage.average'} = $total_cpu_average; + $data->{$entity_value}->{'cpu.usagemhz.average'} = $total_cpu_mhz_average; + $data->{$entity_value}->{'cpu_ready'} = $total_cpu_ready; + $data->{$entity_value}->{'interval_min'} = $interval_min; + $data->{$entity_value}->{'config.annotation'} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef; + $data->{$entity_value}->{'cpu'} = {}; foreach my $id (sort { my ($cida, $cia) = split /:/, $a; my ($cidb, $cib) = split /:/, $b; @@ -191,12 +115,12 @@ sub run { my ($counter_id, $instance) = split /:/, $id; next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); if ($instance ne "") { - $self->{manager}->{output}->perfdata_add(label => 'cpu_' . $instance . '_MHz' . $extra_label, unit => 'MHz', - value => centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id})), - min => 0); + $data->{$entity_value}->{cpu}->{$instance} = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id})); } } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm index 2426c793e..0c2d70b5e 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm @@ -38,51 +38,20 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_on', 'critical_on', 'warning_off', 'critical_off', 'warning_suspended', 'critical_suspended')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.name', 'vm', 'summary.accessible'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } my @vm_array = (); foreach my $entity_view (@$result) { @@ -94,20 +63,12 @@ sub run { my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Datastores are ok")); - } + my $data = {}; + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'} }; + next if (centreon::vmware::common::is_accessible(accessible => $entity_view->{'summary.accessible'}) == 0); - foreach my $entity_view (@$result) { - next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, - name => $entity_view->{'summary.name'}, - state => $entity_view->{'summary.accessible'}, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{'summary.name'} if ($multiple == 1); my %vm_states = (poweredon => 0, poweredoff => 0, suspended => 0); if (defined($entity_view->vm)) { foreach my $vm_host (@{$entity_view->vm}) { @@ -121,30 +82,10 @@ sub run { } } - foreach my $labels ((['poweredon', 'warning_on', 'critical_on'], - ['poweredoff', 'warning_off', 'critical_off'], - ['suspended', 'warning_suspended', 'critical_suspended'])) { - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $vm_states{$labels->[0]}, - threshold => [ { label => $labels->[2], exit_litteral => 'critical' }, - { label => $labels->[1], exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{'summary.name'}, - $vm_states{$labels->[0]}, - $labels->[0])); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' %s VM(s) %s", $entity_view->{'summary.name'}, - $vm_states{$labels->[0]}, - $labels->[0])); - } - - $self->{manager}->{output}->perfdata_add(label => $labels->[0] . $extra_label, - value => $vm_states{$labels->[0]}, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[1]), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => $labels->[2]), - min => 0, max => $vm_states{poweredoff} + $vm_states{suspended} + $vm_states{poweredon}); - } + $data->{$entity_value} = { %{$data->{$entity_value}}, %vm_states }; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm index 567cf9b71..ae1cbfd1f 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm @@ -39,63 +39,30 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning', 'critical')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'config.fileSystemVolume.mountInfo', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - my %uuid_list = (); #my %disk_name = (); my $query_perfs = []; @@ -108,12 +75,11 @@ sub run { $ds_regexp = qr/$self->{datastore_name}/; } + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, datastore => {} }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); my $instances = []; foreach (@{$entity_view->{'config.fileSystemVolume.mountInfo'}}) { @@ -147,8 +113,7 @@ sub run { } if (scalar(@$query_perfs) == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't get a single datastore."); + centreon::vmware::common::set_response(code => 100, short_message => "Can't get a single datastore."); return ; } @@ -162,8 +127,6 @@ sub run { skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Datastore latencies are ok")); foreach my $entity_view (@$result) { next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; @@ -177,37 +140,14 @@ sub run { my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalReadLatency.average'}->{'key'} . ":" . $uuid})); my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.totalWriteLatency.average'}->{'key'} . ":" . $uuid})); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read on '%s' is %s ms", - $entity_view->{name}, $uuid_list{$uuid}, $read_counter)); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' read on '%s' is %s ms", - $entity_view->{name}, $uuid_list{$uuid}, $read_counter)); - } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write on '%s' is %s ms", - $entity_view->{name}, $uuid_list{$uuid}, $write_counter)); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' write on '%s' is %s ms", - $entity_view->{name}, $uuid_list{$uuid}, $write_counter)); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'trl' . $extra_label . '_' . $uuid_list{$uuid}, unit => 'ms', - value => $read_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'twl' . $extra_label . '_' . $uuid_list{$uuid}, unit => 'ms', - value => $write_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $data->{$entity_value}->{datastore}->{$uuid_list{$uuid}} = { + 'datastore.totalReadLatency.average' => $read_counter, + 'datastore.totalWriteLatency.average' => $write_counter, + }; } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm index ee1b66bf8..1462da448 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm @@ -38,49 +38,21 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning', 'critical')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.name', 'summary.accessible'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); @@ -95,58 +67,22 @@ sub run { skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All datastore rates are ok")); - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, - name => $entity_view->{'summary.name'}, - state => $entity_view->{'summary.accessible'}, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'} }; + next if (centreon::vmware::common::is_accessible(accessible => $entity_view->{'summary.accessible'}) == 0); # in KBps my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"})) * 1024; my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"})) * 1024; - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - my ($read_value, $read_unit) = $self->{manager}->{perfdata}->change_bytes(value => $read_counter); - my ($write_value, $write_unit) = $self->{manager}->{perfdata}->change_bytes(value => $write_counter); - - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Rate of reading data: %s Rate of writing data: %s", - $entity_view->{'summary.name'}, - $read_value . " " . $read_unit . "/s", - $write_value . " " . $write_unit . "/s")); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Rate of reading data: %s Rate of writing data: %s", - $entity_view->{'summary.name'}, - $read_value . " " . $read_unit . "/s", - $write_value . " " . $write_unit . "/s")); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{'summary.name'} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'read_rate' . $extra_label, unit => 'B/s', - value => $read_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'write_rate' . $extra_label, unit => 'B/s', - value => $write_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $data->{$entity_value}->{'datastore.read.average'} = $read_counter; + $data->{$entity_value}->{'datastore.write.average'} = $write_counter; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index e03cd012c..0093f6c04 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -38,72 +38,34 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning', 'critical')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} - -sub initArgs { - my ($self, %options) = @_; - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Datastore IOPS counters are ok")); - } - + my $data = {}; #my %uuid_list = (); my %disk_name = (); my %datastore_lun = (); my $ds_checked = 0; foreach (@$result) { - next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, - name => $_->{'summary.name'}, - state => $_->{'summary.accessible'}, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + $data->{$_->{'summary.name'}} = { name => $_->{'summary.name'}, state => $_->{'summary.accessible'} }; + next if (centreon::vmware::common::is_accessible(accessible => $_->{'summary.accessible'}) == 0); if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; @@ -122,8 +84,7 @@ sub run { } if ($ds_checked == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "No Vmfs datastore(s) checked. Cannot get iops from Nas datastore(s)"); + centreon::vmware::common::set_response(code => 100, short_message => "No Vmfs datastore(s) checked. Cannot get iops from Nas datastore(s)"); return ; } @@ -140,8 +101,7 @@ sub run { } if (scalar(@vm_array) == 0) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => "No virtual machines on the datastore"); + centreon::vmware::common::set_response(code => 200, short_message => "No virtual machines on the datastore"); return ; } @@ -160,9 +120,8 @@ sub run { $ref_ids_vm{${$result2}[$i]->{mo_ref}->{value}} = ${$result2}[$i]->{name}; } - if ($multiple == 0 && scalar(@{$result2}) == 0) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => "No active virtual machines on the datastore"); + if (scalar(@{$result2}) == 0) { + centreon::vmware::common::set_response(code => 200, short_message => "No active virtual machines on the datastore"); return ; } @@ -200,65 +159,36 @@ sub run { my $total_read_counter = $datastore_lun{$_}{'disk.numberRead.summation'}; my $total_write_counter = $datastore_lun{$_}{'disk.numberWrite.summation'}; - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read iops on '%s'", - $total_read_counter, $_)); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' read iops on '%s'", - $total_read_counter, $_)); - $self->vm_iops_details(label => 'disk.numberRead.summation', - type => 'read', - detail => $datastore_lun{$_}, - ref_vm => \%ref_ids_vm); - } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write iops on '%s'", - $total_write_counter, $_)); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' write iops on '%s'", - $total_write_counter, $_)); - $self->vm_iops_details(label => 'disk.numberWrite.summation', - type => 'write', - detail => $datastore_lun{$_}, - ref_vm => \%ref_ids_vm) - } + $data->{$_}->{'disk.numberRead.summation'} = $total_read_counter; + $data->{$_}->{'disk.numberWrite.summation'} = $total_write_counter; + $data->{$_}->{vm} = {}; - my $extra_label = ''; - $extra_label = '_' . $_ if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'riops' . $extra_label, unit => 'iops', - value => $total_read_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'wiops' . $extra_label, unit => 'iops', - value => $total_write_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $self->vm_iops_details(label => 'disk.numberRead.summation', + type => 'read', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm, + data => $data); + $self->vm_iops_details(label => 'disk.numberWrite.summation', + type => 'write', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm, + data_vm => $data->{$_}->{vm}); } + + centreon::vmware::common::set_response(data => $data); } sub vm_iops_details { my ($self, %options) = @_; - $self->{manager}->{output}->output_add(long_msg => sprintf(" VM IOPs details: ")); - my $num = 0; foreach my $value (keys %{$options{detail}}) { # display only for high iops if ($value =~ /^vm.*?$options{label}$/ && $options{detail}->{$value} >= $self->{detail_iops_min}) { my ($vm_id) = split(/_/, $value); - $num++; - $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s' %s iops", $options{ref_vm}->{$vm_id}, $options{detail}->{$value})); + $options{data_vm}->{$options{ref_vm}->{$vm_id}} = {} if (!defined($options{data_vm}->{$options{ref_vm}->{$vm_id}})); + $options{data_vm}->{$options{ref_vm}->{$vm_id}}->{$options{label}} = $options{detail}->{$value}; } } - - if ($num == 0) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" no vm with iops >= %s", $self->{detail_iops_min})); - } } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm index 5b550f14b..7a47a7f83 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm @@ -38,60 +38,32 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning_total', 'critical_total', 'warning_snapshot', 'critical_snapshot')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_total', 'critical_total', 'warning_snapshot', 'critical_snapshot')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } -} - sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); my @properties = ('summary.accessible', 'summary.name', 'browser'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } my @ds_array = (); my %ds_names = (); + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, - name => $entity_view->{'summary.name'}, - state => $entity_view->{'summary.accessible'}, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { + name => $entity_view->{'summary.name'}, + state => $entity_view->{'summary.accessible'}, + error_message => '', + snapshost => [], + }; + next if (centreon::vmware::common::is_accessible(accessible => $entity_view->{'summary.accessible'}) == 0); if (defined($entity_view->browser)) { push @ds_array, $entity_view->browser; $ds_names{$entity_view->{mo_ref}->{value}} = $entity_view->{'summary.name'}; @@ -102,15 +74,12 @@ sub run { my $result2; return if (!($result2 = centreon::vmware::common::get_views($self->{connector}, \@ds_array, \@properties))); - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All snapshot sizes are ok")); foreach my $browse_ds (@$result2) { my $dsName; my $tmp_name = $browse_ds->{mo_ref}->{value}; $tmp_name =~ s/^datastoreBrowser-//i; $dsName = $ds_names{$tmp_name}; - $self->{manager}->{output}->output_add(long_msg => "Checking datastore '$dsName':"); my ($snapshots, $msg) = centreon::vmware::common::search_in_datastore( connector => $self->{connector}, browse_ds => $browse_ds, @@ -125,48 +94,21 @@ sub run { if ($msg =~ /NoPermissionFault/i) { $msg = "Not enough permissions"; } - if ($multiple == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Datastore '%s' %s", $dsName, $msg)); - } + + $data->{$tmp_name}->{error_message} = $msg; next; } - my $total_size = 0; - my $lwarn = ''; - my $lcrit = ''; foreach (@$snapshots) { if (defined($_->file)) { foreach my $x (@{$_->file}) { - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $x->fileSize, threshold => [ { label => 'critical_snapshot', exit_litteral => 'critical' }, { label => 'warning_snapshot', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->set_status(exit_litteral => $exit); - my ($size_value, $size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $x->fileSize); - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s: snapshot [%s]=>[%s] [size = %s]", - $exit, $_->folderPath, $x->path, $size_value . ' ' . $size_unit)); - $total_size += $x->fileSize; + push @{$data->{$tmp_name}->{snapshost}}, { folder_path => $_->folderPath, path => $x->path, size => $x->fileSize }; } } } - - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_size, threshold => [ { label => 'critical_total', exit_litteral => 'critical' }, { label => 'warning_total', exit_litteral => 'warning' } ]); - my ($size_value, $size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_size); - $self->{manager}->{output}->set_status(exit_litteral => $exit); - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s: total snapshots [size = %s]", - $exit, $size_value . ' ' . $size_unit)); - - my $extra_label = ''; - $extra_label = '_' . $dsName if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'total_size' . $extra_label, unit => 'B', - value => $total_size, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_total'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_total'), - min => 0); } - if (!$self->{manager}->{output}->is_status(compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{manager}->{output}->get_litteral_status(), - short_msg => sprintf("Snapshot sizes exceed limits")); - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index 9c48cd711..fe78d9379 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -38,43 +38,13 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (!defined($options{arguments}->{units}) || $options{arguments}->{units} !~ /^(%|B)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong units option '" . (defined($options{arguments}->{units}) ? $options{arguments}->{units} : 'null') . "'."); - $self->{output}->option_exit(); - } - foreach my $label (('warning', 'critical', 'warning_provisioned', 'critical_provisioned')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } + return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical', 'warning_provisioned', 'critical_provisioned')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } -} - sub run { my $self = shift; @@ -85,103 +55,31 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Datastore usages are ok")); - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::datastore_state(connector => $self->{connector}, - name => $entity_view->summary->name, - state => $entity_view->summary->accessible, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { name => $entity_view->summary->name, state => $entity_view->summary->accessible }; + next if (centreon::vmware::common::is_accessible(accessible => $entity_view->summary->accessible) == 0); # capacity 0... if ($entity_view->summary->capacity <= 0) { - if ($multiple == 0) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("datastore size is 0")); - } + $data->{$entity_value}->{size} = 0; next; } - + # in Bytes - my $exits = []; - my $name_storage = $entity_view->summary->name; - my $total_size = $entity_view->summary->capacity; - my $total_free = $entity_view->summary->freeSpace; - my $total_used = $total_size - $total_free; - my $prct_used = $total_used * 100 / $total_size; - my $prct_free = 100 - $prct_used; + $data->{$entity_value}->{size} = $entity_view->summary->capacity; + $data->{$entity_value}->{free} = $entity_view->summary->freeSpace; my ($total_uncommited, $prct_uncommited); my $msg_uncommited = ''; if (defined($entity_view->summary->uncommitted)) { - $total_uncommited = $total_used + $entity_view->summary->uncommitted; - $prct_uncommited = $total_uncommited * 100 / $total_size; - my ($total_uncommited_value, $total_uncommited_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_uncommited); - $msg_uncommited = sprintf(" Provisioned: %s (%.2f%%)", $total_uncommited_value . " " . $total_uncommited_unit, $prct_uncommited); - push @{$exits}, $self->{manager}->{perfdata}->threshold_check(value => $prct_uncommited, threshold => [ { label => 'critical_provisioned', exit_litteral => 'critical' }, { label => 'warning_provisioned', exit_litteral => 'warning' } ]); - } - - my ($threshold_value); - $threshold_value = $total_used; - $threshold_value = $total_free if (defined($self->{free})); - if ($self->{units} eq '%') { - $threshold_value = $prct_used; - $threshold_value = $prct_free if (defined($self->{free})); - } - push @{$exits}, $self->{manager}->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit = $self->{manager}->{output}->get_most_critical(status => $exits); - - my ($total_size_value, $total_size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_size); - my ($total_used_value, $total_used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_used); - my ($total_free_value, $total_free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_free); - - $self->{manager}->{output}->output_add(long_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)%s", $name_storage, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free, - $msg_uncommited)); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)%s", $name_storage, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free, - $msg_uncommited)); - } - - my $label = 'used'; - my $value_perf = $total_used; - if (defined($self->{free})) { - $label = 'free'; - $value_perf = $total_free; - } - my $extra_label = ''; - $extra_label = '_' . $name_storage if ($multiple == 1); - my %total_options = (); - if ($self->{units} eq '%') { - $total_options{total} = $total_size; - $total_options{cast_int} = 1; - } - $self->{manager}->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), - min => 0, max => $total_size); - if (defined($total_uncommited)) { - $self->{manager}->{output}->perfdata_add(label => 'provisioned' . $extra_label, unit => 'B', - value => $total_uncommited, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_provisioned', total => $total_size, cast_int => 1), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_provisioned', total => $total_size, cast_int => 1), - min => 0, max => $total_size); + $data->{$entity_value}->{uncommitted} = $entity_view->summary->uncommitted; } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index b323956f0..599920e1b 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -39,56 +39,22 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datastore name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datastore name cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{nopoweredon_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); - return 1; - } - foreach my $label (('warning', 'critical', 'warning_max_total_latency', 'critical_max_total_latency')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} - -sub initArgs { - my ($self, %options) = @_; - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical', 'warning_max_total_latency', 'critical_max_total_latency')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } @@ -105,9 +71,6 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } my $ds_regexp; if (defined($self->{datastore_name}) && !defined($self->{filter_datastore})) { $ds_regexp = qr/^\Q$self->{datastore_name}\E$/; @@ -117,16 +80,21 @@ sub run { $ds_regexp = qr/$self->{datastore_name}/; } + my $data = {}; my $mapped_datastore = {}; my @ds_array = (); foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - power => $entity_view->{'runtime.powerState'}->val, - status => $self->{disconnect_status}, - powerstatus => $self->{nopoweredon_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + datastore => {}, + }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + if (defined($entity_view->datastore)) { foreach (@{$entity_view->datastore}) { if (!defined($mapped_datastore->{$_->value})) { @@ -173,20 +141,15 @@ sub run { if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { $interval_sec = $self->{sampling_period}; } - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Datastore IOPS counters are ok")); + my $finded = 0; foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0 && centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); - my $entity_value = $entity_view->{mo_ref}->{value}; - my $prefix_msg = "'$entity_view->{name}'"; - if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && - $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; - } + $data->{$entity_value}->{'config.annotation'} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef; - $finded |= 1; my %datastore_lun = (); foreach (keys %{$values->{$entity_value}}) { my ($id, $disk_name) = split /:/; @@ -200,62 +163,21 @@ sub run { $datastore_lun{$disk_name{$disk_name}}->{$self->{connector}->{perfcounter_cache_reverse}->{$id}} += $values->{$entity_value}->{$_}; } - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); foreach (sort keys %datastore_lun) { - $finded |= 2; my $read_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberRead.summation'} / $interval_sec)); my $write_counter = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($datastore_lun{$_}{'disk.numberWrite.summation'} / $interval_sec)); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("%s read iops on '%s' is %s", - $prefix_msg, $_, $read_counter)); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s read iops on '%s' is %s", - $prefix_msg, $_, $read_counter)); - } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("%s write iops on '%s' is %s", - $prefix_msg, $_, $write_counter)); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s write iops on '%s' is %s", - $prefix_msg, $_, $write_counter)); - } - - $self->{manager}->{output}->perfdata_add(label => 'riops' . $extra_label . '_' . $_, unit => 'iops', - value => $read_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'wiops' . $extra_label . '_' . $_, unit => 'iops', - value => $write_counter, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $data->{$entity_value}->{datastore}->{$_} = { + 'disk.numberRead.summation' => $read_counter, + 'disk.numberWrite.summation' => $write_counter, + }; } my $max_total_latency = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'disk.maxTotalLatency.latest'}->{key} . ":"})); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $max_total_latency, threshold => [ { label => 'critical_max_total_latency', exit_litteral => 'critical' }, { label => 'warning_max_total_latency', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("%s max total latency is %s ms", - $prefix_msg, $max_total_latency)); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s max total latency is %s ms", - $prefix_msg, $max_total_latency)); - } - $self->{manager}->{output}->perfdata_add(label => 'max_total_latency' . $extra_label, unit => 'ms', - value => $max_total_latency, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_max_total_latency'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_max_total_latency'), - min => 0); + $data->{$entity_value}->{'disk.maxTotalLatency.latest'} = $max_total_latency; } - if (($finded & 2) == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't get a single datastore."); - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index 4ef09179b..baa6095c7 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -38,23 +38,10 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning', 'critical', 'warning_state', 'critical_state')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } + return 0; } @@ -64,31 +51,22 @@ sub initArgs { foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical', 'warning_state', 'critical_state')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + centreon::vmware::common::init_response(identity => $options{arguments}->{identity}); } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'summary.hardware.memorySize', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } + my $performances = [{'label' => 'mem.consumed.average', 'instances' => ['']}, {'label' => 'mem.overhead.average', 'instances' => ['']}]; if (!defined($self->{no_memory_state})) { @@ -108,17 +86,13 @@ sub run { # 3 (low) 1% my %mapping_state = (0 => 'high', 1 => 'soft', 2 => 'hard', 3 => 'low'); - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All memory usages are ok")); - } + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + my $memory_size = $entity_view->{'summary.hardware.memorySize'}; # in B # in KB @@ -128,70 +102,14 @@ sub run { if (!defined($self->{no_memory_state})) { $mem_state = centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.state.latest'}->{'key'} . ":"}); } - my $mem_free = $memory_size - $mem_used; - my $prct_used = $mem_used * 100 / $memory_size; - my $prct_free = 100 - $prct_used; - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); - my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_used); - my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); - - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my $output = sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - my $exit2 = 'OK'; - if (!defined($self->{no_memory_state})) { - $output = sprintf("Memory state : %s", $mapping_state{$mem_state}); - $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $mem_state, threshold => [ { label => 'critical_state', exit_litteral => 'critical' }, { label => 'warning_state', exit_litteral => 'warning' } ]); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - } - - my $prefix_msg = "'$entity_view->{name}'"; - $self->{manager}->{output}->output_add(long_msg => "$prefix_msg $long_msg"); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => "$prefix_msg $short_msg" - ); - } - if ($multiple == 0) { - $self->{manager}->{output}->output_add(short_msg => "$prefix_msg $long_msg"); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $mem_used, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', total => $memory_size, cast_int => 1), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', total => $memory_size, cast_int => 1), - min => 0, max => $memory_size); - $self->{manager}->{output}->perfdata_add(label => 'overhead' . $extra_label, unit => 'B', - value => $mem_overhead, - min => 0); - if (!defined($self->{no_memory_state})) { - $self->{manager}->{output}->perfdata_add(label => 'state' . $extra_label, - value => $mem_state, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_state'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_state'), - min => 0, max => 3); - } + $data->{$entity_value}->{mem_size} = $memory_size; + $data->{$entity_value}->{'mem.consumed.average'} = $mem_used; + $data->{$entity_value}->{'mem.overhead.average'} = $mem_overhead; + $data->{$entity_value}->{mem_state} = defined($mem_state) ? $mapping_state{$mem_state} : undef; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index 429a73403..222742b89 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -38,62 +38,22 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{nic_name}) && $options{arguments}->{nic_name} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: nic name cannot be null"); - return 1; - } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{link_down_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{link_down_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for link down status '" . $options{arguments}->{link_down_status} . "'"); - return 1; - } - foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out', - 'warning_dropped_in', 'critical_dropped_in', 'warning_dropped_out', 'critical_dropped_out')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} - -sub initArgs { - my ($self, %options) = @_; - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out', - 'warning_dropped_in', 'critical_dropped_in', 'warning_dropped_out', 'critical_dropped_out')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my ($multiple, $number_nic) = (0, 0); + my $number_nic = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'config.network.pnic', 'runtime.connectionState', 'config.network.vswitch'); if (!defined($self->{no_proxyswitch})) { @@ -101,83 +61,49 @@ sub run { } my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All traffics are ok")); - } - + + my $data = {}; my $pnic_def_up = {}; - my $pnic_def_down = {}; my $query_perfs = []; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - $pnic_def_up->{$entity_view->{mo_ref}->{value}} = {}; - $pnic_def_down->{$entity_view->{mo_ref}->{value}} = {}; - my %nic_in_vswitch = (); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val, + pnic => { }, vswitch => { }, proxyswitch => {} }; + next if ($entity_view->{'runtime.connectionState'}->val !~ /^connected$/i); + + $pnic_def_up->{$entity_value} = {}; my $instances = []; - my $filter_ok = 0; # Get Name from vswitch if (defined($entity_view->{'config.network.vswitch'})) { foreach (@{$entity_view->{'config.network.vswitch'}}) { + $data->{$entity_value}->{vswitch}->{$_->{name}} = { pnic => [] }; next if (!defined($_->{pnic})); - foreach my $keynic (@{$_->{pnic}}) { - $nic_in_vswitch{$keynic} = 1; - } + push @{$data->{$entity_value}->{vswitch}->{$_->{name}}->{pnic}}, @{$_->{pnic}}; } } # Get Name from proxySwitch if (defined($entity_view->{'config.network.proxySwitch'})) { foreach (@{$entity_view->{'config.network.proxySwitch'}}) { + $data->{$entity_value}->{proxyswitch}->{$_->{name}} = { pnic => [] }; next if (!defined($_->{pnic})); - foreach my $keynic (@{$_->{pnic}}) { - $nic_in_vswitch{$keynic} = 1; - } + push @{$data->{$entity_value}->{proxyswitch}->{$_->{name}}->{pnic}}, @{$_->{pnic}}; } } foreach (@{$entity_view->{'config.network.pnic'}}) { - # Not in vswitch. Skip - next if (!defined($nic_in_vswitch{$_->key})); - - # Check filter - if (defined($self->{nic_name}) && !defined($self->{filter_nic}) && $_->device ne $self->{nic_name}) { - next; - } elsif (defined($self->{nic_name}) && defined($self->{filter_nic}) && $_->device !~ /$self->{nic_name}/) { - next; - } - $filter_ok = 1; + $data->{$entity_value}->{pnic}->{$_->device} = { speed => undef, status => 'down', key => $_->{key} }; + $number_nic++; if (defined($_->linkSpeed)) { - $pnic_def_up->{$entity_view->{mo_ref}->{value}}->{$_->device} = $_->linkSpeed->speedMb; + $data->{$entity_value}->{pnic}->{$_->device}->{speed} = $_->linkSpeed->speedMb; + $data->{$entity_value}->{pnic}->{$_->device}->{status} = 'up'; + + $pnic_def_up->{$entity_value}->{$_->device} = $_->linkSpeed->speedMb; push @$instances, $_->device; - } else { - $pnic_def_down->{$entity_view->{mo_ref}->{value}}->{$_->device} = 1; } } - - if ($filter_ok == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("%s can't get physical nic with filter '%s'. (or physical nic not in a 'vswitch' or 'dvswitch'", - $entity_view->{name}, $self->{nic_name})); - next; - } - if (scalar(@$instances) == 0 && - ($multiple == 0 || ($multiple == 1 && !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1)))) { - $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, - short_msg => sprintf("%s Link(s) '%s' is/are down", - $entity_view->{name}, join("', '", keys %{$pnic_def_down->{$entity_view->{mo_ref}->{value}}}))); - next; - } - + push @$query_perfs, { entity => $entity_view, metrics => [ @@ -204,106 +130,26 @@ sub run { foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - if (scalar(keys %{$pnic_def_down->{$entity_value}}) > 0 && - (($multiple == 0 && $number_nic == 1) || !$self->{manager}->{output}->is_status(value => $self->{link_down_status}, compare => 'ok', litteral => 1))) { - ($number_nic == 1) ? my $be = "is" : my $be = "are"; - $self->{manager}->{output}->output_add(severity => $self->{link_down_status}, - short_msg => sprintf("%s Link(s) '%s' %s down", - $entity_view->{name}, join("', '", keys %{$pnic_def_down->{$entity_value}}), $be)); - } - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$pnic_def_up->{$entity_value}}) { - my $interface = sprintf("Interface '%s'", $_); - my $output = ''; + foreach (sort keys %{$pnic_def_up->{$entity_value}}) { # KBps my $traffic_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_})) * 1024 * 8; my $traffic_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_})) * 1024 * 8; - my $interface_speed = $pnic_def_up->{$entity_value}->{$_} * 1024 * 1024; - my $in_prct = $traffic_in * 100 / $interface_speed; - my $out_prct = $traffic_out * 100 / $interface_speed; - - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical_in', exit_litteral => 'critical' }, { label => 'warning_in', exit_litteral => 'warning' } ]); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical_out', exit_litteral => 'critical' }, { label => 'warning_out', exit_litteral => 'warning' } ]); - - my ($in_value, $in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $traffic_in, network => 1); - my ($out_value, $out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $traffic_out, network => 1); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - push @exits, $exit; - - $output = sprintf("Traffic In : %s/s (%.2f %%), Out : %s/s (%.2f %%)", - $in_value . $in_unit, $in_prct, - $out_value . $out_unit, $out_prct); - $long_msg .= $long_msg_append . $interface . " " . $output; - $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0 && $number_nic == 1)) { - $short_msg .= $short_msg_append . $interface . " " . $output; - $short_msg_append = ', '; - } - - my $extra_label = ''; - $extra_label .= '_' . $_ if ($number_nic > 1); - $extra_label .= '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'traffic_in' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $traffic_in), - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-in', total => $interface_speed), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-in', total => $interface_speed), - min => 0, max => $interface_speed); - $self->{manager}->{output}->perfdata_add(label => 'traffic_out' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $traffic_out), - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-out', total => $interface_speed), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-out', total => $interface_speed), - min => 0, max => $interface_speed); - - # Packets dropped my $packets_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.packetsRx.summation'}->{key} . ":" . $_})); my $packets_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.packetsTx.summation'}->{key} . ":" . $_})); my $dropped_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedRx.summation'}->{key} . ":" . $_})); my $dropped_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedTx.summation'}->{key} . ":" . $_})); - my $dropped_in_prct = ($packets_in > 0) ? $dropped_in * 100 / $packets_in : 0; - my $dropped_out_prct = ($packets_out > 0) ? $dropped_out * 100 / $packets_out : 0; - - my $exit3 = $self->{manager}->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical_dropped_in', exit_litteral => 'critical' }, { label => 'warning_dropped_in', exit_litteral => 'warning' } ]); - my $exit4 = $self->{manager}->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical_dropped_out', exit_litteral => 'critical' }, { label => 'warning_dropped_out', exit_litteral => 'warning' } ]); - - my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit3, $exit4 ]); - push @exits, $exit; - - $output = sprintf("Packets In Dropped : %.2f %% (%d/%d packets), Packets Out Dropped : %.2f %% (%d/%d packets)", - $dropped_in_prct, $dropped_in, $packets_in, - $dropped_out_prct, $dropped_out, $packets_out); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0 && $number_nic == 1)) { - $short_msg .= $short_msg_append . $interface . " " . $output; - $short_msg_append = ', '; - } - - $self->{manager}->{output}->perfdata_add(label => 'packets_dropped_in' . $extra_label, unit => '%', - value => sprintf("%.2f", $dropped_in_prct), - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-dropped-in'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-dropped-in'), - min => 0, max => 100); - $self->{manager}->{output}->perfdata_add(label => 'packets_dropped_out' . $extra_label, unit => '%', - value => sprintf("%.2f", $dropped_out_prct), - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning-dropped-out'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical-dropped-out'), - min => 0, max => 100); - } - - $self->{manager}->{output}->output_add(long_msg => "'$entity_view->{name}' $long_msg"); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => "'$entity_view->{name}' $short_msg" - ); - } - if ($multiple == 0) { - $self->{manager}->{output}->output_add(short_msg => "'$entity_view->{name}' $long_msg"); + + $data->{$entity_value}->{pnic}->{$_}->{'net.received.average'} = $traffic_in; + $data->{$entity_value}->{pnic}->{$_}->{'net.transmitted.average'} = $traffic_out; + $data->{$entity_value}->{pnic}->{$_}->{'net.packetsRx.summation'} = $packets_in; + $data->{$entity_value}->{pnic}->{$_}->{'net.packetsTx.summation'} = $packets_out; + $data->{$entity_value}->{pnic}->{$_}->{'net.droppedRx.summation'} = $dropped_in; + $data->{$entity_value}->{pnic}->{$_}->{'net.droppedTx.summation'} = $dropped_out; } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 03871dd51..db1258ac1 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -25,36 +25,49 @@ use VMware::VIRuntime; use VMware::VILib; use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); -use centreon::plugins::options; -use centreon::plugins::output; -use centreon::plugins::perfdata; +use JSON; my $manager_display = {}; +my $manager_response = {}; my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; -sub init_response { - $manager_display->{options} = centreon::plugins::options->new(); - $manager_display->{output} = centreon::plugins::output->new(options => $manager_display->{options}); - $manager_display->{perfdata} = centreon::plugins::perfdata->new(output => $manager_display->{output}); +sub set_response { + my (%options) = @_; - return $manager_display; + $manager_response->{code} = $options{code} if (defined($options{code})); + $manager_response->{short_message} = $options{short_message} if (defined($options{short_message})); + $manager_response->{extra_message} = $options{extra_message} if (defined($options{extra_message})); + $manager_response->{identity} = $options{identity} if (defined($options{identity})); + $manager_response->{data} = $options{data} if (defined($options{data})); +} + +sub init_response { + my (%options) = @_; + + $manager_response->{code} = 0; + $manager_response->{short_message} = 'OK'; + $manager_response->{extra_message} = ''; + $manager_response->{identity} = $options{identity} if (defined($options{identity})); + $manager_response->{data} = {}; } sub free_response { - $manager_display = {}; + $manager_response = {}; } sub response { my (%options) = @_; - my $stdout = ''; - if (!defined($options{stdout})) { - local *STDOUT; - $manager_display->{output}->{option_results}->{output_json} = 1; - open STDOUT, '>', \$stdout; - $manager_display->{output}->display(force_long_output => 1, nolabel => 1); + my $response_str = ''; + if (defined($options{force_response})) { + $response_str = $options{force_response}; } else { - $stdout = $options{stdout}; + eval { + $response_str = JSON->new->utf8->encode($manager_response); + }; + if ($@) { + $response_str = '{ "code": -1, "short_message": "Cannot encode result" }'; + } } if (defined($options{reinit})) { @@ -70,7 +83,7 @@ sub response { zmq_msg_send($msg, $options{endpoint}, $flag); zmq_msg_close($msg); } - my $msg = zmq_msg_init_data($options{token} . " " . $stdout); + my $msg = zmq_msg_init_data($options{token} . " " . $response_str); zmq_msg_send($msg, $options{endpoint}, ZMQ_NOBLOCK); zmq_msg_close($msg); } @@ -78,14 +91,12 @@ sub response { sub vmware_error { my ($obj_vmware, $lerror) = @_; - $manager_display->{output}->output_add(long_msg => $lerror); + set_response(extra_message => $lerror); $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $lerror"); if ($lerror =~ /NoPermissionFault/i) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'VMWare error: not enought permissions'); + set_response(code => -1, short_message => 'VMWare error: not enought permissions'); } else { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'VMWare error (verbose mode for more details)'); + set_response(code => -1, short_message => 'VMWare error (verbose mode for more details)'); } return undef; } @@ -220,11 +231,11 @@ sub get_perf_metric_ids { foreach (@{$options{metrics}}) { if (defined($options{connector}->{perfcounter_cache}->{$_->{label}})) { if ($options{interval} != 20 && $options{connector}->{perfcounter_cache}->{$_->{label}}{level} > $options{connector}->{sampling_periods}->{$options{interval}}->{level}) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", - $_->{label}, $options{interval}, - $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, - $options{connector}->{sampling_periods}->{$options{interval}}->{level})); + set_response(code => -1, + short_message => sprintf("Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", + $_->{label}, $options{interval}, + $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, + $options{connector}->{sampling_periods}->{$options{interval}}->{level})); return undef; } foreach my $instance (@{$_->{instances}}) { @@ -234,8 +245,7 @@ sub get_perf_metric_ids { } } else { $options{connector}->{logger}->writeLogError("Metric '" . $_->{label} . "' unavailable."); - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Counter doesn't exist. VMware version can be too old."); + set_response(code => -1, short_message => "Counter doesn't exist. VMware version can be too old."); return undef; } } @@ -337,13 +347,11 @@ sub generic_performance_values_historic { } # check sampling period exist (period 20 is not listed) if ($interval != 20 && !defined($obj_vmware->{sampling_periods}->{$interval})) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Sampling period '%s' not managed.", $interval)); + set_response(code => -1, short_message => sprintf("Sampling period '%s' not managed.", $interval)); return undef; } if ($interval != 20 && $obj_vmware->{sampling_periods}->{$interval}->{enabled} != 1) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Sampling period '%s' collection data no enabled.", $interval)); + set_response(code => -1, short_message => sprintf("Sampling period '%s' collection data no enabled.", $interval)); return undef; } eval { @@ -362,8 +370,7 @@ sub generic_performance_values_historic { return undef if (!defined($perfdata)); if (!$$perfdata[0] || !defined($$perfdata[0]->value)) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Cannot get value for counters (Maybe, object(s) cannot be reached: disconnected, not running, time not synced (see time-host mode),...)'); + set_response(code => -1, short_message => 'Cannot get value for counters (Maybe, object(s) cannot be reached: disconnected, not running, time not synced (see time-host mode),...)'); return undef; } foreach my $val (@$perfdata) { @@ -372,8 +379,7 @@ sub generic_performance_values_historic { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; next; } elsif (!defined($_->value)) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also)'); + set_response(code => -1, short_message => 'Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also)'); return undef; } @@ -400,9 +406,8 @@ sub generic_performance_values_historic { }; if ($@) { if ($@ =~ /querySpec.interval.*InvalidArgumentFault/msi) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Interval '%s' is surely not supported for the managed entity (caller: %s)", - $interval, join('--', caller))); + set_response(code => -1, short_message => sprintf("Interval '%s' is surely not supported for the managed entity (caller: %s)", + $interval, join('--', caller))); } else { $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); } @@ -463,8 +468,7 @@ sub search_entities { } if (scalar(@$temp_views) == 0) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot find '$$scope[1]' object"); + set_response(code => 1, short_message => "Cannot find '$$scope[1]' object"); return undef; } push @$begin_views, @$temp_views; @@ -487,8 +491,7 @@ sub search_entities { push @$results, @$views; } if (scalar(@$results) == 0) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot find '$options{view_type}' object"); + set_response(code => 1, short_message => "Cannot find '$options{view_type}' object"); return undef; } return $results; @@ -526,8 +529,7 @@ sub find_entity_views { if (!defined($entity_views) || scalar(@$entity_views) == 0) { my $status = 0; if (!defined($options{output_message}) || $options{output_message} != 0) { - $manager_display->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot find '$options{view_type}' object"); + set_response(code => 1, short_message => "Cannot find '$options{view_type}' object"); } return (0, undef); } @@ -684,18 +686,11 @@ sub strip_cr { sub stats_info { my (%options) = @_; - my $total = 0; + my $data = {}; foreach my $container (keys %{$options{counters}}) { - $total += $options{counters}->{$container}; - $options{manager}->{output}->perfdata_add(label => 'c[requests_' . $container . ']', - value => $options{counters}->{$container}, - min => 0); + $data->{$container} = { requests => $options{counters}->{$container} }; } - $options{manager}->{output}->perfdata_add(label => 'c[requests]', - value => $total, - min => 0); - $options{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("'%s' total requests", $total)); + set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 56e7c1b5f..31c190baf 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -125,10 +125,8 @@ sub handle_CHLD { sub response_router { my ($self, %options) = @_; - my $manager = centreon::vmware::common::init_response(); - $manager->{output}->output_add(severity => $options{severity}, - short_msg => $options{msg}); - $manager->{output}->{plugin} = $options{identity}; + centreon::vmware::common::init_response(identity => $options{identity}); + centreon::vmware::common::set_response(code => $options{code}, short_message => $options{msg}); centreon::vmware::common::response(token => 'RESPSERVER2', endpoint => $backend); centreon::vmware::common::free_response(); } @@ -144,7 +142,7 @@ sub verify_child { delete $self->{return_child}->{$self->{child_proc}->{$_}->{pid}}; delete $self->{child_proc}->{$_}; } elsif (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { - $self->response_router(severity => 'UNKNOWN', msg => 'Timeout process', + $self->response_router(code => -1, msg => 'Timeout process', identity => $_); kill('INT', $self->{child_proc}->{$_}->{pid}); delete $self->{child_proc}->{$_}; @@ -191,7 +189,7 @@ sub reqclient { exit(0); } } else { - $self->response_router(severity => 'UNKNOWN', msg => 'Container connection problem', + $self->response_router(code => -1, msg => 'Container connection problem', identity => $result->{identity}); } } @@ -228,7 +226,7 @@ sub run { zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); zmq_setsockopt($backend, ZMQ_LINGER, 0); # we discard zmq_connect($backend, 'ipc:///tmp/centreon_vmware/routing.ipc'); - centreon::vmware::common::response(token => 'READY', endpoint => $backend, stdout => ''); + centreon::vmware::common::response(token => 'READY', endpoint => $backend, force_response => ''); # Initialize poll set my @poll = ( From fbe1d897e9a42b6f47a29b2dcf33b396f636dbe0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 30 Jan 2019 18:29:00 +0100 Subject: [PATCH 195/447] WIP: new version centreon-vmware 3.0.0 --- .../src/centreon/script/centreon_vmware.pm | 2 +- .../vmware/src/centreon/vmware/cmdcpuvm.pm | 2 +- .../src/centreon/vmware/cmddatastorevm.pm | 2 +- .../vmware/src/centreon/vmware/cmddevicevm.pm | 85 ++++--------------- .../src/centreon/vmware/cmddiscovery.pm | 22 +---- .../vmware/src/centreon/vmware/common.pm | 4 +- .../vmware/src/centreon/vmware/connector.pm | 4 +- 7 files changed, 26 insertions(+), 95 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 132d636a5..202c84ae9 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::script); use vars qw(%centreon_vmware_config); -my $VERSION = "2.4.0"; +my $VERSION = "3.0.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 90dfdf213..806dedd4a 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -91,6 +91,7 @@ sub run { name => $entity_view->{name}, connection_state => $entity_view->{'runtime.connectionState'}->val, power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, }; next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); @@ -104,7 +105,6 @@ sub run { $data->{$entity_value}->{'cpu.usagemhz.average'} = $total_cpu_mhz_average; $data->{$entity_value}->{'cpu_ready'} = $total_cpu_ready; $data->{$entity_value}->{'interval_min'} = $interval_min; - $data->{$entity_value}->{'config.annotation'} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef; $data->{$entity_value}->{'cpu'} = {}; foreach my $id (sort { my ($cida, $cia) = split /:/, $a; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 599920e1b..300d0ca60 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -90,6 +90,7 @@ sub run { name => $entity_view->{name}, connection_state => $entity_view->{'runtime.connectionState'}->val, power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, datastore => {}, }; next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); @@ -148,7 +149,6 @@ sub run { next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0 && centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); - $data->{$entity_value}->{'config.annotation'} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef; my %datastore_lun = (); foreach (keys %{$values->{$entity_value}}) { diff --git a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm index f39aba832..470e382c4 100644 --- a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm @@ -30,7 +30,6 @@ sub new { bless $self, $class; $self->{commandName} = 'devicevm'; - return $self; } @@ -38,57 +37,21 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{nopoweredon_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -102,44 +65,32 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - + my $data = {}; my $total_device_connected = 0; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - power => $entity_view->{'runtime.powerState'}->val, - status => $self->{disconnect_status}, - powerstatus => $self->{nopoweredon_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + total_device_connected => 0, + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); foreach my $dev (@{$entity_view->{'config.hardware.device'}}) { if (ref($dev) =~ /$self->{device}/) { if ($dev->connectable->connected == 1) { - my $prefix_msg = "'$entity_view->{name}'"; - if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && - $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; - } - $self->{manager}->{output}->output_add(long_msg => sprintf("%s device connected", - $prefix_msg)); - $total_device_connected++; + $data->{$entity_value}->{total_device_connected}++; } } } } - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_device_connected, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s %s device connected", $total_device_connected, $self->{device})); - $self->{manager}->{output}->perfdata_add(label => 'connected', - value => $total_device_connected, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index a1f4ee63f..551d7c4b6 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -23,7 +23,6 @@ use base qw(centreon::vmware::cmdbase); use strict; use warnings; use centreon::vmware::common; -use JSON::XS; sub new { my ($class, %options) = @_; @@ -41,16 +40,6 @@ sub checkArgs { return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; @@ -147,17 +136,8 @@ sub run { $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; $disco_stats->{discovered_items} = @disco_data; $disco_stats->{results} = \@disco_data; - - my $encoded_data; - eval { - $encoded_data = encode_json($disco_stats); - }; - if ($@) { - $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; - } - $self->{manager}->{output}->output_add(short_msg => $encoded_data); - $self->{manager}->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + centreon::vmware::common::set_response(data => $disco_stats); } 1; diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index db1258ac1..976f2e3be 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -25,7 +25,7 @@ use VMware::VIRuntime; use VMware::VILib; use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); -use JSON; +use JSON::XS;; my $manager_display = {}; my $manager_response = {}; @@ -63,7 +63,7 @@ sub response { $response_str = $options{force_response}; } else { eval { - $response_str = JSON->new->utf8->encode($manager_response); + $response_str = JSON::XS->new->utf8->encode($manager_response); }; if ($@) { $response_str = '{ "code": -1, "short_message": "Cannot encode result" }'; diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 31c190baf..76448ff19 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -21,7 +21,7 @@ package centreon::vmware::connector; use strict; use VMware::VIRuntime; use VMware::VILib; -use JSON; +use JSON::XS; use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); use File::Basename; @@ -167,7 +167,7 @@ sub reqclient { my $result; eval { - $result = JSON->new->utf8->decode($options{data}); + $result = JSON::XS->new->utf8->decode($options{data}); }; if ($@) { $self->{logger}->writeLogError("Cannot decode JSON: $@ (options{data}"); From 678d3267619c92975f88cdf41516a63b3e8048c0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 31 Jan 2019 11:57:52 +0100 Subject: [PATCH 196/447] WIP: centreon-vmware 3.0.0 --- .../vmware/src/centreon/common/logger.pm | 218 ++++++++++++++++++ connectors/vmware/src/centreon/script.pm | 94 ++++++++ .../src/centreon/script/centreon_vmware.pm | 19 +- .../vmware/src/centreon/vmware/cmdgetmap.pm | 40 ++-- .../src/centreon/vmware/cmdhealthhost.pm | 113 +++------ .../vmware/src/centreon/vmware/cmdlimitvm.pm | 123 ++-------- .../src/centreon/vmware/cmdlistclusters.pm | 39 +--- .../src/centreon/vmware/cmdlistdatacenters.pm | 39 +--- .../src/centreon/vmware/cmdlistdatastores.pm | 46 +--- .../src/centreon/vmware/cmdlistnichost.pm | 45 +--- .../src/centreon/vmware/cmdmaintenancehost.pm | 60 +---- .../vmware/src/centreon/vmware/cmdmemhost.pm | 9 - .../vmware/src/centreon/vmware/cmdmemvm.pm | 125 ++-------- .../src/centreon/vmware/cmdservicehost.pm | 82 ++----- .../src/centreon/vmware/cmdsnapshotvm.pm | 116 ++-------- .../src/centreon/vmware/cmdstatushost.pm | 66 +----- .../vmware/src/centreon/vmware/cmdstatusvm.pm | 72 ++---- .../vmware/src/centreon/vmware/cmdswaphost.pm | 88 +------ .../vmware/src/centreon/vmware/cmdswapvm.pm | 111 ++------- .../centreon/vmware/cmdthinprovisioningvm.pm | 98 ++------ .../vmware/src/centreon/vmware/cmdtimehost.pm | 85 +------ .../vmware/src/centreon/vmware/cmdtoolsvm.pm | 114 ++------- .../src/centreon/vmware/cmduptimehost.pm | 87 +------ .../centreon/vmware/cmdvmoperationcluster.pm | 111 +-------- .../vmware/src/centreon/vmware/common.pm | 70 +----- .../vmware/src/centreon/vmware/connector.pm | 5 - 26 files changed, 601 insertions(+), 1474 deletions(-) create mode 100644 connectors/vmware/src/centreon/common/logger.pm create mode 100644 connectors/vmware/src/centreon/script.pm diff --git a/connectors/vmware/src/centreon/common/logger.pm b/connectors/vmware/src/centreon/common/logger.pm new file mode 100644 index 000000000..1f726c128 --- /dev/null +++ b/connectors/vmware/src/centreon/common/logger.pm @@ -0,0 +1,218 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::common::logger; + +=head1 NOM + +centreon::common::logger - Simple logging module + +=head1 SYNOPSIS + + #!/usr/bin/perl -w + + use strict; + use warnings; + + use centreon::polling; + + my $logger = new centreon::common::logger(); + + $logger->writeLogInfo("information"); + +=head1 DESCRIPTION + +This module offers a simple interface to write log messages to various output: + +* standard output +* file +* syslog + +=cut + +use strict; +use warnings; +use Sys::Syslog qw(:standard :macros); +use IO::Handle; + +my %severities = (1 => LOG_INFO, + 2 => LOG_ERR, + 4 => LOG_DEBUG); + +sub new { + my $class = shift; + + my $self = bless + { + file => 0, + filehandler => undef, + # 0 = nothing, 1 = critical, 3 = info, 7 = debug + severity => 3, + old_severity => 3, + # 0 = stdout, 1 = file, 2 = syslog + log_mode => 0, + # Output pid of current process + withpid => 0, + # syslog + log_facility => undef, + log_option => LOG_PID, + }, $class; + return $self; +} + +sub file_mode($$) { + my ($self, $file) = @_; + + if (defined($self->{filehandler})) { + $self->{filehandler}->close(); + } + if (open($self->{filehandler}, ">>", $file)){ + $self->{log_mode} = 1; + $self->{filehandler}->autoflush(1); + $self->{file_name} = $file; + return 1; + } + $self->{filehandler} = undef; + print STDERR "Cannot open file $file: $!\n"; + return 0; +} + +sub is_file_mode { + my $self = shift; + + if ($self->{log_mode} == 1) { + return 1; + } + return 0; +} + +sub is_debug { + my $self = shift; + + if (($self->{severity} & 4) == 0) { + return 0; + } + return 1; +} + +sub syslog_mode($$$) { + my ($self, $logopt, $facility) = @_; + + $self->{log_mode} = 2; + openlog($0, $logopt, $facility); + return 1; +} + +# For daemons +sub redirect_output { + my $self = shift; + + if ($self->is_file_mode()) { + open my $lfh, '>>', $self->{file_name}; + open STDOUT, '>&', $lfh; + open STDERR, '>&', $lfh; + } +} + +sub set_default_severity { + my $self = shift; + + $self->{severity} = $self->{old_severity}; +} + +# Getter/Setter Log severity +sub severity { + my $self = shift; + if (@_) { + my $save_severity = $self->{severity}; + if ($_[0] =~ /^[012347]$/) { + $self->{severity} = $_[0]; + } elsif ($_[0] eq "none") { + $self->{severity} = 0; + } elsif ($_[0] eq "error") { + $self->{severity} = 1; + } elsif ($_[0] eq "info") { + $self->{severity} = 3; + } elsif ($_[0] eq "debug") { + $self->{severity} = 7; + } else { + $self->writeLogError("Wrong severity value set."); + return -1; + } + $self->{old_severity} = $save_severity; + } + return $self->{severity}; +} + +sub withpid { + my $self = shift; + if (@_) { + $self->{withpid} = $_[0]; + } + return $self->{withpid}; +} + +sub get_date { + my $self = shift; + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time()); + return sprintf("%04d-%02d-%02d %02d:%02d:%02d", + $year+1900, $mon+1, $mday, $hour, $min, $sec); +} + +sub writeLog($$$%) { + my ($self, $severity, $msg, %options) = @_; + my $withdate = (defined $options{withdate}) ? $options{withdate} : 1; + $msg = ($self->{withpid} == 1) ? "$$ - $msg " : $msg; + my $newmsg = ($withdate) + ? $self->get_date . " - $msg" : $msg; + + if (($self->{severity} & $severity) == 0) { + return; + } + if ($self->{log_mode} == 0) { + print "$newmsg\n"; + } elsif ($self->{log_mode} == 1) { + if (defined $self->{filehandler}) { + print { $self->{filehandler} } "$newmsg\n"; + } + } elsif ($self->{log_mode} == 2) { + syslog($severities{$severity}, $msg); + } +} + +sub writeLogDebug { + shift->writeLog(4, @_); +} + +sub writeLogInfo { + shift->writeLog(2, @_); +} + +sub writeLogError { + shift->writeLog(1, @_); +} + +sub DESTROY { + my $self = shift; + + if (defined $self->{filehandler}) { + $self->{filehandler}->close(); + } +} + +1; diff --git a/connectors/vmware/src/centreon/script.pm b/connectors/vmware/src/centreon/script.pm new file mode 100644 index 000000000..5f83dc1c4 --- /dev/null +++ b/connectors/vmware/src/centreon/script.pm @@ -0,0 +1,94 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::script; + +use strict; +use warnings; +use FindBin; +use Getopt::Long; +use Pod::Usage; +use centreon::common::logger; + +$SIG{__DIE__} = sub { + return unless defined $^S and $^S == 0; # Ignore errors in eval + my $error = shift; + print "Error: $error"; + exit 1; +}; + +sub new { + my ($class, $name, %options) = @_; + my %defaults = + ( + log_file => undef, + severity => "info", + noroot => 0, + ); + my $self = {%defaults, %options}; + + bless $self, $class; + $self->{name} = $name; + $self->{logger} = centreon::common::logger->new(); + $self->{options} = { + "logfile=s" => \$self->{log_file}, + "severity=s" => \$self->{severity}, + "help|?" => \$self->{help} + }; + return $self; +} + +sub init { + my $self = shift; + + if (defined $self->{log_file}) { + $self->{logger}->file_mode($self->{log_file}); + } + $self->{logger}->severity($self->{severity}); + + if ($self->{noroot} == 1) { + # Stop exec if root + if ($< == 0) { + $self->{logger}->writeLogError("Can't execute script as root."); + die("Quit"); + } + } +} + +sub add_options { + my ($self, %options) = @_; + + $self->{options} = {%{$self->{options}}, %options}; +} + +sub parse_options { + my $self = shift; + + Getopt::Long::Configure('bundling'); + die "Command line error" if !GetOptions(%{$self->{options}}); + pod2usage(-exitval => 1, -input => $FindBin::Bin . "/" . $FindBin::Script) if $self->{help}; +} + +sub run { + my $self = shift; + + $self->parse_options(); + $self->init(); +} + +1; diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 202c84ae9..b10e152ed 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -28,7 +28,7 @@ use ZMQ::Constants qw(:all); use File::Basename; use Digest::MD5 qw(md5_hex); use POSIX ":sys_wait_h"; -use JSON; +use JSON::XS; use centreon::script; use centreon::vmware::common; use centreon::vmware::connector; @@ -99,6 +99,7 @@ my @load_modules = ( sub new { my $class = shift; my $self = $class->SUPER::new("centreon_vmware", + # we keep it if we use centreon common library centreon_db_conn => 0, centstorage_db_conn => 0, noconfig => 1 @@ -119,10 +120,6 @@ sub new { dynamic_timeout_kill => 86400, refresh_keeper_session => 15, port => 5700, - datastore_state_error => 'UNKNOWN', - vm_state_error => 'UNKNOWN', - host_state_error => 'UNKNOWN', - retention_dir => '/var/lib/centreon/centplugins', case_insensitive => 0, vsphere_server => { #'default' => {'url' => 'https://XXXXXX/sdk', @@ -139,7 +136,6 @@ sub new { $self->{childs_vpshere_pid} = {}; $self->{counter_stats} = {}; $self->{whoaim} = undef; # to know which vsphere to connect - $self->{module_date_parse_loaded} = 0; $self->{modules_registry} = {}; return $self; @@ -193,12 +189,6 @@ sub init { $self->{centreon_vmware_config}->{vsphere_server}->{$_}->{password} = $lpassword; } } - - eval 'require Date::Parse'; - if (!$@) { - $self->{module_date_parse_loaded} = 1; - require Date::Parse; - } $self->set_signal_handlers; } @@ -381,7 +371,7 @@ sub request { # Decode json my $result; eval { - $result = JSON->new->utf8->decode($options{data}); + $result = JSON::XS->new->utf8->decode($options{data}); }; if ($@) { centreon::vmware::common::set_response(code => 1, short_message => "Cannot decode json result: $@"); @@ -436,7 +426,7 @@ sub repserver { # Decode json my $result; eval { - $result = JSON->new->utf8->decode($options{data}); + $result = JSON::XS->new->utf8->decode($options{data}); }; if ($@) { $self->{logger}->writeLogError("Cannot decode JSON: $@ (options{data}"); @@ -513,7 +503,6 @@ sub create_vsphere_child { if ($child_vpshere_pid == 0) { my $connector = centreon::vmware::connector->new(name => $self->{whoaim}, modules_registry => $self->{modules_registry}, - module_date_parse_loaded => $self->{module_date_parse_loaded}, config => $self->{centreon_vmware_config}, logger => $self->{logger}); $connector->run(); diff --git a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm index f62ac294f..c131dbef5 100644 --- a/connectors/vmware/src/centreon/vmware/cmdgetmap.pm +++ b/connectors/vmware/src/centreon/vmware/cmdgetmap.pm @@ -38,23 +38,12 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; @@ -63,12 +52,16 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("List ESX host(s):")); - + my $data = {}; foreach my $entity_view (@$result) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [v%s] %s", $entity_view->name, $entity_view->{'config.product.version'}, - defined($self->{vm_no}) ? '' : ':')); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + version => $entity_view->{'config.product.version'}, + vm => {} + }; + next if (defined($self->{vm_no})); my @vm_array = (); @@ -80,16 +73,15 @@ sub run { my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); - my %vms = (); foreach my $vm (@$result2) { - $vms{$vm->name} = $vm->{'summary.runtime.powerState'}->val; - } - - foreach (sort keys %vms) { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [%s]", - $_, $vms{$_})); + $data->{$entity_value}->{vm}->{$vm->{mo_ref}->{value}} = { + name => $vm->name, + power_state => $vm->{'summary.runtime.powerState'}->val, + }; } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm index f1d860cb0..14d935bff 100644 --- a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm @@ -38,148 +38,99 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => 0); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => 0); + return 0; } sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All ESX health checks are ok")); - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); - my $OKCount = 0; - my $CAlertCount = 0; - my $WAlertCount = 0; my $cpuStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{cpuStatusInfo}; my $memoryStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{memoryStatusInfo}; my $storageStatusInfo = $entity_view->{'runtime.healthSystemRuntime.hardwareStatusInfo'}->{storageStatusInfo}; my $numericSensorInfo = $entity_view->{'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo'}; - $self->{manager}->{output}->output_add(long_msg => sprintf("Checking %s", $entity_view->{name})); # CPU if (defined($cpuStatusInfo)) { + $data->{$entity_value}->{cpu_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; foreach (@$cpuStatusInfo) { if ($_->status->key =~ /^red$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); - $CAlertCount++; + push @{$data->{$entity_value}->{cpu_info}->{summary_red}}, { name => $_->name, summary => $_->status->summary }; + $data->{$entity_value}->{cpu_info}->{red}++; } elsif ($_->status->key =~ /^yellow$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); - $WAlertCount++; + push @{$data->{$entity_value}->{cpu_info}->{summary_yellow}}, { name => $_->name, summary => $_->status->summary }; + $data->{$entity_value}->{cpu_info}->{yellow}++; } else { - $OKCount++; + $data->{$entity_value}->{cpu_info}->{ok}++; } } } # Memory if (defined($memoryStatusInfo)) { + $data->{$entity_value}->{memory_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; foreach (@$memoryStatusInfo) { if ($_->status->key =~ /^red$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); - $CAlertCount++; + push @{$data->{$entity_value}->{memory_info}->{summary_red}}, { name => $_->name, summary => $_->status->summary }; + $data->{$entity_value}->{memory_info}->{red}++; } elsif ($_->status->key =~ /^yellow$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); - $WAlertCount++; + push @{$data->{$entity_value}->{memory_info}->{summary_yellow}}, { name => $_->name, summary => $_->status->summary }; + $data->{$entity_value}->{memory_info}->{yellow}++; } else { - $OKCount++; + $data->{$entity_value}->{memory_info}->{ok}++; } } } # Storage if (defined($self->{storage_status}) && defined($storageStatusInfo)) { + $data->{$entity_value}->{storage_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; foreach (@$storageStatusInfo) { if ($_->status->key =~ /^red$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); - $CAlertCount++; + push @{$data->{$entity_value}->{storage_info}->{summary_red}}, { name => $_->name, summary => $_->status->summary }; + $data->{$entity_value}->{storage_info}->{red}++; } elsif ($_->status->key =~ /^yellow$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->name . ": " . $_->status->summary); - $WAlertCount++; + push @{$data->{$entity_value}->{storage_info}->{summary_yellow}}, { name => $_->name, summary => $_->status->summary }; + $data->{$entity_value}->{storage_info}->{yellow}++; } else { - $OKCount++; + $data->{$entity_value}->{storage_info}->{ok}++; } } } # Sensor if (defined($numericSensorInfo)) { + $data->{$entity_value}->{sensor_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; foreach (@$numericSensorInfo) { if ($_->healthState->key =~ /^red$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $CAlertCount++; + push @{$data->{$entity_value}->{sensor_info}->{summary_red}}, { type => $_->sensorType, name => $_->name, summary => $_->healthState->summary }; + $data->{$entity_value}->{sensor_info}->{red}++; } elsif ($_->healthState->key =~ /^yellow$/i) { - $self->{manager}->{output}->output_add(long_msg => $_->sensorType . " sensor " . $_->name . ": ".$_->healthState->summary); - $WAlertCount++; + push @{$data->{$entity_value}->{sensor_info}->{summary_yellow}}, { type => $_->sensorType, name => $_->name, summary => $_->healthState->summary }; + $data->{$entity_value}->{sensor_info}->{yellow}++; } else { - $OKCount++; + $data->{$entity_value}->{sensor_info}->{ok}++; } } } - - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $WAlertCount, - threshold => [ { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' %s health issue(s) found", $entity_view->{name}, $WAlertCount)); - } - $exit = $self->{manager}->{perfdata}->threshold_check(value => $CAlertCount, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' } ]); - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' %s health issue(s) found", $entity_view->{name}, $CAlertCount)); - } - - $self->{manager}->{output}->output_add(long_msg => sprintf("%s health checks are green", $OKCount)); - if ($multiple == 0) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("'%s' %s health checks are green", $entity_view->{name}, $OKCount)); - } - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'problems' . $extra_label, - value => $CAlertCount + $WAlertCount, - min => 0, max => $OKCount + $CAlertCount + $WAlertCount); } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index a495034f9..ab6eeeaa3 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -38,64 +38,16 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); - return 1; - } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{cpu_limitset_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{cpu_limitset_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for cpu limitset status '" . $options{arguments}->{cpu_limitset_status} . "'"); - return 1; - } - if (defined($options{arguments}->{memory_limitset_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{memory_limitset_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for memory limitset status '" . $options{arguments}->{memory_limitset_status} . "'"); - return 1; - } - if (defined($options{arguments}->{disk_limitset_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disk_limitset_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disk limitset status '" . $options{arguments}->{disk_limitset_status} . "'"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } + return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - -sub display_verbose { - my ($self, %options) = @_; - - $self->{manager}->{output}->output_add(long_msg => $options{label}); - foreach my $vm (sort keys %{$options{vms}}) { - my $prefix = $vm; - if ($options{vms}->{$vm} ne '') { - $prefix .= ' [' . centreon::vmware::common::strip_cr(value => $options{vms}->{$vm}) . ']'; - } - $self->{manager}->{output}->output_add(long_msg => ' ' . $prefix); - } -} - sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -112,72 +64,47 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All Limits are ok")); - } else { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("Limits are ok")); - } - - my %cpu_limit = (); - my %memory_limit = (); - my %disk_limit = (); + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - nocheck_ps => 1, - multiple => $multiple) == 0); - - next if (defined($self->{nopoweredon_skip}) && - centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + 'config.cpuAllocation.limit' => -1, + 'config.memoryAllocation.limit' => -1, + 'config.storageIOAllocation.limit' => [], + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); # CPU Limit if (defined($entity_view->{'config.cpuAllocation.limit'}) && $entity_view->{'config.cpuAllocation.limit'} != -1) { - $cpu_limit{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; + $data->{$entity_value}->{'config.cpuAllocation.limit'} = $entity_view->{'config.cpuAllocation.limit'}; } # Memory Limit if (defined($entity_view->{'config.memoryAllocation.limit'}) && $entity_view->{'config.memoryAllocation.limit'} != -1) { - $memory_limit{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; + $data->{$entity_value}->{'config.memoryAllocation.limit'} = $entity_view->{'config.memoryAllocation.limit'}; } # Disk if (defined($self->{check_disk_limit})) { + use Data::Dumper; + print Data::Dumper::Dumper($entity_view->{'config.hardware.device'}); foreach my $device (@{$entity_view->{'config.hardware.device'}}) { if ($device->isa('VirtualDisk')) { - if (defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { - $disk_limit{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; - last; - } + if (defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { + push @{$data->{$entity_value}->{'config.storageIOAllocation.limit'}}, { name => $device->backing->fileName, limit => $device->storageIOAllocation->limit }; + } } } - } + } } - if (scalar(keys %cpu_limit) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{cpu_limitset_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{cpu_limitset_status}, - short_msg => sprintf('%d VM with CPU limits', scalar(keys %cpu_limit))); - $self->display_verbose(label => 'CPU limits:', vms => \%cpu_limit); - } - if (scalar(keys %memory_limit) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{memory_limitset_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{memory_limitset_status}, - short_msg => sprintf('%d VM with memory limits', scalar(keys %memory_limit))); - $self->display_verbose(label => 'Memory limits:', vms => \%memory_limit); - } - if (scalar(keys %disk_limit) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{disk_limitset_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{disk_limitset_status}, - short_msg => sprintf('%d VM with disk limits', scalar(keys %disk_limit))); - $self->display_verbose(label => 'Disk limits:', vms => \%disk_limit); - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm b/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm index 9c77d3186..d9ab90e10 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistclusters.pm @@ -38,58 +38,27 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{cluster}) && $options{arguments}->{cluster} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: cluster cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: cluster cannot be null"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'cluster', is_regexp => 'filter'); my @properties = ('name'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); return if (!defined($result)); - if (!defined($self->{disco_show})) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => 'List cluster(s):'); - } + my $data = {}; foreach my $cluster (@$result) { - if (defined($self->{disco_show})) { - $self->{manager}->{output}->add_disco_entry(name => $cluster->name); - } else { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s", - $cluster->name)); - } + $data->{$cluster->{mo_ref}->{value}} = { name => $cluster->name }; } - if (defined($self->{disco_show})) { - my $stdout; - { - local *STDOUT; - $self->{manager}->{output}->{option_results}->{output_xml} = 1; - open STDOUT, '>', \$stdout; - $self->{manager}->{output}->display_disco_show(); - delete $self->{manager}->{output}->{option_results}->{output_xml}; - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => $stdout); - } - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm index 40c0f2ff4..a17c35468 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatacenters.pm @@ -38,58 +38,27 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{datacenter}) && $options{arguments}->{datacenter} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: datacenter cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: datacenter cannot be null"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); my @properties = ('name'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => $filters); return if (!defined($result)); - if (!defined($self->{disco_show})) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => 'List datacenter(s):'); - } + my $data = {}; foreach my $datacenter (@$result) { - if (defined($self->{disco_show})) { - $self->{manager}->{output}->add_disco_entry(name => $datacenter->name); - } else { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s", - $datacenter->name)); - } + $data->{$datacenter->{mo_ref}->{value}} = { name => $datacenter->{name} }; } - if (defined($self->{disco_show})) { - my $stdout; - { - local *STDOUT; - $self->{manager}->{output}->{option_results}->{output_xml} = 1; - open STDOUT, '>', \$stdout; - $self->{manager}->{output}->display_disco_show(); - delete $self->{manager}->{output}->{option_results}->{output_xml}; - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => $stdout); - } - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm index 5a2e00f94..05a12c7b3 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistdatastores.pm @@ -38,23 +38,12 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; @@ -65,35 +54,16 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - if (!defined($self->{disco_show})) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => 'List datastore(s):'); - } + my $data = {}; foreach my $datastore (@$result) { - if (defined($self->{disco_show})) { - $self->{manager}->{output}->add_disco_entry(name => $datastore->summary->name, - accessible => $datastore->summary->accessible, - type => $datastore->summary->type); - } else { - $self->{manager}->{output}->output_add(long_msg => sprintf(" %s [%s] [%s]", - $datastore->summary->name, - $datastore->summary->accessible, - $datastore->summary->type)); - } + $data->{$datastore->{mo_ref}->{value}} = { + name => $datastore->summary->name, + type => $datastore->summary->type, + accessible => $datastore->summary->accessible + }; } - if (defined($self->{disco_show})) { - my $stdout; - { - local *STDOUT; - $self->{manager}->{output}->{option_results}->{output_xml} = 1; - open STDOUT, '>', \$stdout; - $self->{manager}->{output}->display_disco_show(); - delete $self->{manager}->{output}->{option_results}->{output_xml}; - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => $stdout); - } - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm index d95c4d35f..8dd883f3b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlistnichost.pm @@ -38,23 +38,12 @@ sub checkArgs { my ($self, %options) = @_; if (!defined($options{arguments}->{esx_hostname}) || $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname need to be set"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname need to be set"); return 1; } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; my %nic_in_vswitch = (); @@ -82,11 +71,6 @@ sub run { } } } - - if (!defined($self->{disco_show})) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => 'List nic host:'); - } my %nics = (); foreach (@{$$result[0]->{'config.network.pnic'}}) { @@ -99,33 +83,16 @@ sub run { $nics{$_->device}{down} = 1; } } - + + my $data = {}; foreach my $nic_name (sort keys %nics) { my $status = defined($nics{$nic_name}{up}) ? 'up' : 'down'; my $vswitch = defined($nics{$nic_name}{vswitch}) ? 1 : 0; - if (defined($self->{disco_show})) { - $self->{manager}->{output}->add_disco_entry(name => $nic_name, - status => $status, - vswitch => $vswitch); - } else { - $self->{manager}->{output}->output_add(long_msg => sprintf('%s [status: %s] [vswitch: %s]', - $nic_name, $status, $vswitch)); - } - } - - if (defined($self->{disco_show})) { - my $stdout; - { - local *STDOUT; - $self->{manager}->{output}->{option_results}->{output_xml} = 1; - open STDOUT, '>', \$stdout; - $self->{manager}->{output}->display_disco_show(); - delete $self->{manager}->{output}->{option_results}->{output_xml}; - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => $stdout); - } + $data->{$nic_name} = { name => $nic_name, status => $status, vswitch => $vswitch }; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm index 5f7d7781a..6afae9951 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmaintenancehost.pm @@ -38,74 +38,32 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); - return 1; - } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{maintenance_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{maintenance_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for maintenance status '" . $options{arguments}->{maintenance_status} . "'"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } + return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.inMaintenanceMode', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All ESX maintenance mode are ok")); - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' maintenance mode is %s", - $entity_view->{name}, $entity_view->{'runtime.inMaintenanceMode'})); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); - if ($entity_view->{'runtime.inMaintenanceMode'} =~ /$self->{maintenance_alert}/ && - !$self->{manager}->{output}->is_status(value => $self->{maintenance_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{maintenance_status}, - short_msg => sprintf("'%s' maintenance mode is %s", - $entity_view->{name}, $entity_view->{'runtime.inMaintenanceMode'})) - } elsif ($multiple == 0) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("'%s' maintenance mode is %s", - $entity_view->{name}, $entity_view->{'runtime.inMaintenanceMode'})) - } + $data->{$entity_value}->{inMaintenanceMode} = $entity_view->{'runtime.inMaintenanceMode'}; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index baa6095c7..9aa7e9021 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -45,15 +45,6 @@ sub checkArgs { return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - centreon::vmware::common::init_response(identity => $options{arguments}->{identity}); -} - sub run { my $self = shift; diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index 075a7b08e..a294868ec 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -38,57 +38,21 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{nopoweredon_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -113,24 +77,20 @@ sub run { skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All memory usages are ok")); - } + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - power => $entity_view->{'runtime.powerState'}->val, - status => $self->{disconnect_status}, - powerstatus => $self->{nopoweredon_status}, - multiple => $multiple) == 0); my $entity_value = $entity_view->{mo_ref}->{value}; - my $memory_size = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + # in KB my $mem_consumed = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.consumed.average'}->{'key'} . ":"})) * 1024; my $mem_active = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.active.average'}->{'key'} . ":"})) * 1024; @@ -138,56 +98,15 @@ sub run { my $mem_ballooning = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.vmmemctl.average'}->{'key'} . ":"})) * 1024; my $mem_shared = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.shared.average'}->{'key'} . ":"})) * 1024; - my $mem_free = $memory_size - $mem_consumed; - my $prct_used = $mem_consumed * 100 / $memory_size; - my $prct_free = 100 - $prct_used; - - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($total_value, $total_unit) = $self->{manager}->{perfdata}->change_bytes(value => $memory_size); - my ($used_value, $used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_consumed); - my ($free_value, $free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $mem_free); - - my $prefix_msg = "'$entity_view->{name}'"; - if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && - $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; - } - - $self->{manager}->{output}->output_add(long_msg => sprintf("%s Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $prefix_msg, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $prefix_msg, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $mem_consumed, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', total => $memory_size, cast_int => 1), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', total => $memory_size, cast_int => 1), - min => 0, max => $memory_size); - $self->{manager}->{output}->perfdata_add(label => 'overhead' . $extra_label, unit => 'B', - value => $mem_overhead, - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'ballooning' . $extra_label, unit => 'B', - value => $mem_ballooning, - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'active' . $extra_label, unit => 'B', - value => $mem_active, - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'shared' . $extra_label, unit => 'B', - value => $mem_shared, - min => 0); + $data->{$entity_value}->{'memory_size'} = $entity_view->{'summary.config.memorySizeMB'} * 1024 * 1024; + $data->{$entity_value}->{'mem.consumed.average'} = $mem_consumed; + $data->{$entity_value}->{'mem.active.average'} = $mem_active; + $data->{$entity_value}->{'mem.overhead.average'} = $mem_overhead; + $data->{$entity_value}->{'mem.vmmemctl.average'} = $mem_ballooning; + $data->{$entity_value}->{'mem.shared.average'} = $mem_shared; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm index 24a180931..eea7607e0 100644 --- a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm @@ -38,33 +38,16 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + return 0; } sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.connectionState', 'runtime.inMaintenanceMode', 'configManager.serviceSystem'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); @@ -72,64 +55,43 @@ sub run { my %host_names = (); my @host_array = (); + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - next if (centreon::vmware::common::host_maintenance(connector => $self->{connector}, - hostname => $entity_view->{name}, - maintenance => $entity_view->{'runtime.inMaintenanceMode'}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { name => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + inMaintenanceMode => $entity_view->{'runtime.inMaintenanceMode'}, + services => [], + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_maintenance(maintenance => $entity_view->{'runtime.inMaintenanceMode'}) == 0); + if (defined($entity_view->{'configManager.serviceSystem'})) { push @host_array, $entity_view->{'configManager.serviceSystem'}; $host_names{$entity_view->{'configManager.serviceSystem'}->{value}} = $entity_view->{name}; } } - return if (scalar(@host_array) == 0); + if (scalar(@host_array) == 0) { + centreon::vmware::common::set_response(data => $data); + return ; + } @properties = ('serviceInfo'); my $result2 = centreon::vmware::common::get_views($self->{connector}, \@host_array, \@properties); return if (!defined($result2)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All ESX services are ok")); - } - foreach my $entity (@$result2) { my $hostname = $host_names{$entity->{mo_ref}->{value}}; - - my @services_ok = (); - my @services_problem = (); + foreach my $service (@{$entity->{serviceInfo}->{service}}) { - next if (defined($self->{filter_services}) && $self->{filter_services} ne '' && - $service->{key} !~ /$self->{filter_services}/); - - if ($service->{policy} =~ /^on|automatic/i && !$service->{running}) { - push @services_problem, $service->{key}; - } else { - push @services_ok, $service->{key}; - } - } - - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' services [ ok : %s ] [ nok : %s ]", $hostname, - join(', ', @services_ok), join(', ', @services_problem))); - my $status = 'OK'; - $status = 'CRITICAL' if (scalar(@services_problem) > 0); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $status, - short_msg => sprintf("'%s' services [ ok : %s ] [ nok : %s ]", $hostname, - join(', ', @services_ok), join(', ', @services_problem))); + push @{$data->{$entity->{mo_ref}->{value}}->{services}}, { label => $service->{label}, policy => $service->{policy}, running => $service->{running} }; } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm index 43add42a1..b86b4e890 100644 --- a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm @@ -38,49 +38,16 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning', 'critical')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} - -sub initArgs { - my ($self, %options) = @_; - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning', 'critical')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; - if ($self->{connector}->{module_date_parse_loaded} == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Need to install Date::Parse CPAN Module"); - return ; - } - - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -99,79 +66,32 @@ sub run { my %vm_consolidate = (); my %vm_errors = (warning => {}, critical => {}); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All snapshots are ok")); - } else { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("Snapshot(s) OK")); - } + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - nocheck_ps => 1, - multiple => $multiple) == 0); - - next if (defined($self->{nopoweredon_skip}) && - centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); - + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + snapshosts => [], + }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + if (defined($self->{check_consolidation}) && defined($entity_view->{'runtime.consolidationNeeded'}) && $entity_view->{'runtime.consolidationNeeded'} =~ /^true|1$/i) { - $vm_consolidate{$entity_view->{name}} = 1; + $data->{$entity_value}->{consolidation_needed} = 1; } next if (!defined($entity_view->{'snapshot.rootSnapshotList'})); foreach my $snapshot (@{$entity_view->{'snapshot.rootSnapshotList'}}) { # 2012-09-21T14:16:17.540469Z - my $create_time = Date::Parse::str2time($snapshot->createTime); - if (!defined($create_time)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't Parse date '" . $snapshot->createTime . "' for vm '" . $entity_view->{name} . "'"); - next; - } - - my $diff_time = time() - $create_time; - my $days = int($diff_time / 60 / 60 / 24); - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - my $prefix_msg = "'$entity_view->{name}'"; - if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && - $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; - } - if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $vm_errors{$exit}->{$entity_view->{name}} = 1; - $self->{manager}->{output}->output_add(long_msg => "$prefix_msg snapshot create time: " . $snapshot->createTime); - } + push @{$data->{$entity_value}->{snapshosts}}, { name => $snapshot->name, description => $snapshot->description, create_time => $snapshot->createTime }; } } - - $self->{manager}->{output}->perfdata_add(label => 'num_warning', - value => scalar(keys %{$vm_errors{warning}}), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'num_critical', - value => scalar(keys %{$vm_errors{critical}}), - min => 0); - if (scalar(keys %{$vm_errors{warning}}) > 0) { - $self->{manager}->{output}->output_add(severity => 'WARNING', - short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{warning} / 86400), - join('] [', sort keys %{$vm_errors{warning}}))); - } - if (scalar(keys %{$vm_errors{critical}}) > 0) { - $self->{manager}->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{critical} / 86400), - join('] [', sort keys %{$vm_errors{critical}}))); - } - if (scalar(keys %vm_consolidate) > 0) { - $self->{manager}->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf('VMs need consolidation: [%s]', - join('] [', sort keys %vm_consolidate))); - } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm index 6031c5f85..c2094f67f 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatushost.pm @@ -38,75 +38,31 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + return 0; } sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } - my %overallStatus = ( - 'gray' => 'status is unknown', - 'green' => 'is OK', - 'red' => 'has a problem', - 'yellow' => 'might have a problem', - ); - my %overallStatusReturn = ( - 'gray' => 'UNKNOWN', - 'green' => 'OK', - 'red' => 'CRITICAL', - 'yellow' => 'WARNING' - ); - - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All ESX are ok")); + + my $data = {}; + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + + $data->{$entity_value}->{overall_status} = $entity_view->{'summary.overallStatus'}->val; } - foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - - my $status_esx = $entity_view->{'summary.overallStatus'}->val; - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); - - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $overallStatusReturn{$status_esx}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $overallStatusReturn{$status_esx}, - short_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); - } - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm index ea07c3b45..47d2d81c9 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm @@ -38,82 +38,44 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + return 0; } sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; } - my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); + my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; } my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - my %overallStatus = ( - 'gray' => 'status is unknown', - 'green' => 'is OK', - 'red' => 'has a problem', - 'yellow' => 'might have a problem', - ); - my %overallStatusReturn = ( - 'gray' => 'UNKNOWN', - 'green' => 'OK', - 'red' => 'CRITICAL', - 'yellow' => 'WARNING' - ); + my $data = {}; + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All virtual machines are ok")); + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + + $data->{$entity_value}->{overall_status} = $entity_view->{'summary.overallStatus'}->val; } - foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - nocheck_ps => 1, - multiple => $multiple) == 0); - - my $status_vm = $entity_view->{'summary.overallStatus'}->val; - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_vm})); - - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $overallStatusReturn{$status_vm}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $overallStatusReturn{$status_vm}, - short_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_vm})); - } - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm index 1956635e1..b2fd7dbc4 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswaphost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswaphost.pm @@ -38,59 +38,26 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; - } + return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); -} - sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'mem.swapinRate.average', 'instances' => ['']}, @@ -100,54 +67,21 @@ sub run { skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All swap rate usages are ok")); - } + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); - my $entity_value = $entity_view->{mo_ref}->{value}; + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); # KBps my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"})) * 1024; my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"})) * 1024; - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); - my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); - - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Swap In: %s Swap Out: %s", - $entity_view->{name}, - $swap_in_value . " " . $swap_in_unit . "/s", - $swap_out_value . " " . $swap_out_unit . "/s")); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Swap In: %s Swap Out: %s", - $entity_view->{name}, - $swap_in_value . " " . $swap_in_unit . "/s", - $swap_out_value . " " . $swap_out_unit . "/s")); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'swap_in' . $extra_label, unit => 'B/s', - value => $swap_in, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'swap_out' . $extra_label, unit => 'B/s', - value => $swap_out, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $data->{$entity_value}->{'mem.swapinRate.average'} = $swap_in; + $data->{$entity_value}->{'mem.swapoutRate.average'} = $swap_out; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm index e20af75f9..9ff70ad67 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -38,57 +38,21 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (defined($options{arguments}->{nopoweredon_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{nopoweredon_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for nopoweredon status '" . $options{arguments}->{nopoweredon_status} . "'"); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); + return 0; } sub run { my $self = shift; if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -111,66 +75,29 @@ sub run { skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All swap rate usages are ok")); - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - power => $entity_view->{'runtime.powerState'}->val, - status => $self->{disconnect_status}, - powerstatus => $self->{nopoweredon_status}, - multiple => $multiple) == 0); - my $entity_value = $entity_view->{mo_ref}->{value}; + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); # KBps my $swap_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapinRate.average'}->{'key'} . ":"})) * 1024; my $swap_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'mem.swapoutRate.average'}->{'key'} . ":"})) * 1024; - my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $swap_in, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $swap_out, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - my ($swap_in_value, $swap_in_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_in); - my ($swap_out_value, $swap_out_unit) = $self->{manager}->{perfdata}->change_bytes(value => $swap_out); - - my $prefix_msg = "'$entity_view->{name}'"; - if (defined($self->{display_description}) && defined($entity_view->{'config.annotation'}) && - $entity_view->{'config.annotation'} ne '') { - $prefix_msg .= ' [' . centreon::vmware::common::strip_cr(value => $entity_view->{'config.annotation'}) . ']'; - } - - $self->{manager}->{output}->output_add(long_msg => sprintf("%s Swap In: %s Swap Out: %s", - $prefix_msg, - $swap_in_value . " " . $swap_in_unit . "/s", - $swap_out_value . " " . $swap_out_unit . "/s")); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("%s Swap In: %s Swap Out: %s", - $prefix_msg, - $swap_in_value . " " . $swap_in_unit . "/s", - $swap_out_value . " " . $swap_out_unit . "/s")); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'swap_in' . $extra_label, unit => 'B/s', - value => $swap_in, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{manager}->{output}->perfdata_add(label => 'swap_out' . $extra_label, unit => 'B/s', - value => $swap_out, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $data->{$entity_value}->{'mem.swapinRate.average'} = $swap_in; + $data->{$entity_value}->{'mem.swapoutRate.average'} = $swap_out; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index 17ca1a231..5b60267b7 100644 --- a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -38,55 +38,16 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{thinprovisioning_status}) && $options{arguments}->{thinprovisioning_status} ne '') { - my ($entry, $status) = split /,/, $options{arguments}->{thinprovisioning_status}; - if ($entry !~ /^(notactive|active)$/) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Wrong thinprovisioning-status option. Can only be 'active' or 'noactive'. Not: '" . $entry . "'."); - return 1; - } - if ($options{manager}->{output}->is_litteral_status(status => $status) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Wrong thinprovisioning-status option. Not a good status: '" . $status . "'."); - return 1; - } - } + return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; -} - -sub display_verbose { - my ($self, %options) = @_; - - foreach my $vm (sort keys %{$options{vms}}) { - my $prefix = $vm; - if ($options{vms}->{$vm}->{description} ne '') { - $prefix .= ' [' . centreon::vmware::common::strip_cr(value => $options{vms}->{$vm}->{description}) . ']'; - } - $self->{manager}->{output}->output_add(long_msg => $prefix); - foreach my $disk (sort keys %{$options{vms}->{$vm}->{disks}}) { - $self->{manager}->{output}->output_add(long_msg => ' ' . $disk); - } - } -} - sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -100,55 +61,28 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All thinprovisoning virtualdisks are ok.")); - } else { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("Thinprovisoning virtualdisks are ok.")); - } - - my $disks_vm = {}; - my %maps_match = ('active' => { regexp => '^1$', output => 'VirtualDisks thinprovisioning actived' }, - 'notactive' => { regexp => '^(?!(1)$)', output => 'VirtualDisks thinprovisioning not actived' }); - my $num = 0; - my ($entry, $status); - if (defined($self->{thinprovisioning_status}) && $self->{thinprovisioning_status} ne '') { - ($entry, $status) = split /,/, $self->{thinprovisioning_status}; - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - nocheck_ps => 1, - multiple => $multiple) == 0); - - next if (defined($self->{nopoweredon_skip}) && - centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + disks => [], + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); foreach (@{$entity_view->{'config.hardware.device'}}) { if ($_->isa('VirtualDisk')) { - if (defined($entry) && $_->backing->thinProvisioned =~ /$maps_match{$entry}->{regexp}/) { - $num++; - if (!defined($disks_vm->{$entity_view->{name}})) { - $disks_vm->{$entity_view->{name}} = { disks => {}, description => (defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : '') }; - } - $disks_vm->{$entity_view->{name}}->{disks}->{$_->backing->fileName} = 1; - } + push @{$data->{$entity_value}->{disks}}, { thin_provisioned => $_->backing->thinProvisioned, name => $_->backing->fileName }; } } } - if ($num > 0) { - $self->{manager}->{output}->output_add(severity => $status, - short_msg => sprintf('%d %s', $num, $maps_match{$entry}->{output})); - $self->display_verbose(vms => $disks_vm); - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm index d6f7014a7..c9559e978 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtimehost.pm @@ -38,70 +38,29 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - foreach my $label (('warning_time', 'critical_time')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } - return 0; -} - -sub initArgs { - my ($self, %options) = @_; - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_time', 'critical_time')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } + return 0; } sub run { my $self = shift; - if ($self->{connector}->{module_date_parse_loaded} == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Need to install Date::Parse CPAN Module"); - return ; - } - - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'configManager.dateTimeSystem', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => 'All Times are ok'); - } + my $data = {}; my @host_array = (); foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->{val}, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + if (defined($entity_view->{'configManager.dateTimeSystem'})) { push @host_array, $entity_view->{'configManager.dateTimeSystem'}; } @@ -111,39 +70,17 @@ sub run { my $result2 = centreon::vmware::common::get_views($self->{connector}, \@host_array, \@properties); return if (!defined($result2)); - my $localtime = time(); foreach my $entity_view (@$result) { my $host_dts_value = $entity_view->{'configManager.dateTimeSystem'}->{value}; foreach my $host_dts_view (@$result2) { - if ($host_dts_view->{mo_ref}->{value} eq $host_dts_value) { - my $time = $host_dts_view->QueryDateTime(); - my $timestamp = Date::Parse::str2time($time); - my $offset = $localtime - $timestamp; - - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $offset, threshold => [ { label => 'critical_time', exit_litteral => 'critical' }, { label => 'warning_time', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' date: %s, offset: %s second(s)", - $entity_view->{name}, - $time, $offset)); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Time offset %d second(s) : %s", - $entity_view->{name}, $offset, - $time)); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'offset' . $extra_label, unit => 's', - value => $offset, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_time'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_time'), - min => 0); - + if ($host_dts_view->{mo_ref}->{value} eq $host_dts_value) { + $data->{$entity_view->{mo_ref}->{value}}->{current_time} = $host_dts_view->QueryDateTime(); last; } } } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index fe9e7b80b..28d122a21 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -38,45 +38,11 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: vm hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); return 1; } - if (defined($options{arguments}->{tools_notinstalled_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{tools_notinstalled_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for tools notinstalled status '" . $options{arguments}->{tools_notinstalled_status} . "'"); - return 1; - } - if (defined($options{arguments}->{tools_notrunning_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{tools_notrunning_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for tools notrunning status '" . $options{arguments}->{tools_notrunning_status} . "'"); - return 1; - } - if (defined($options{arguments}->{tools_notupd2date_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{tools_notupd2date_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for tools notupd2date status '" . $options{arguments}->{tools_notupd2date_status} . "'"); - return 1; - } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - return 0; -} -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + return 0; } sub display_verbose { @@ -95,7 +61,6 @@ sub display_verbose { sub run { my $self = shift; - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); if (defined($self->{filter_description}) && $self->{filter_description} ne '') { $filters->{'config.annotation'} = qr/$self->{filter_description}/; @@ -109,71 +74,22 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All VMTools are OK")); - } else { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("VMTools are OK")); - } - my %not_installed = (); - my %not_running = (); - my %not_up2date = (); + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::vm_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - nocheck_ps => 1, - multiple => $multiple) == 0); - - next if (defined($self->{nopoweredon_skip}) && - centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); - - my $tools_status = lc($entity_view->{'summary.guest.toolsStatus'}->val); - if ($tools_status eq 'toolsnotinstalled') { - $not_installed{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; - } elsif ($tools_status eq 'toolsnotrunning') { - $not_running{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; - } elsif ($tools_status eq 'toolsold') { - $not_up2date{$entity_view->{name}} = defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : ''; - } + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + $data->{$entity_value}->{tools_status} = defined($entity_view->{'summary.guest.toolsStatus'}) ? $entity_view->{'summary.guest.toolsStatus'}->val : undef; } - if (scalar(keys %not_up2date) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{tools_notupd2date_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{tools_notupd2date_status}, - short_msg => sprintf('%d VM with VMTools not up-to-date', scalar(keys %not_up2date))); - $self->display_verbose(label => 'vmtools not up-to-date:', vms => \%not_up2date); - } - if (scalar(keys %not_running) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{tools_notrunning_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{tools_notrunning_status}, - short_msg => sprintf('%d VM with VMTools not running', scalar(keys %not_running))); - $self->display_verbose(label => 'vmtools not running:', vms => \%not_running); - } - if (scalar(keys %not_installed) > 0 && - !$self->{manager}->{output}->is_status(value => $self->{tools_notinstalled_status}, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $self->{tools_notinstalled_status}, - short_msg => sprintf('%d VM with VMTools not installed', scalar(keys %not_installed))); - $self->display_verbose(label => 'vmtools not installed:', vms => \%not_installed); - } - - if ($multiple == 1) { - my $total = scalar(keys %not_up2date) + scalar(keys %not_running) + scalar(keys %not_installed); - $self->{manager}->{output}->perfdata_add(label => 'not_updated', - value => scalar(keys %not_up2date), - min => 0, max => $total); - $self->{manager}->{output}->perfdata_add(label => 'not_running', - value => scalar(keys %not_running), - min => 0, max => $total); - $self->{manager}->{output}->perfdata_add(label => 'not_installed', - value => scalar(keys %not_installed), - min => 0, max => $total); - } + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmduptimehost.pm b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm index 321795c68..e19697fd2 100644 --- a/connectors/vmware/src/centreon/vmware/cmduptimehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmduptimehost.pm @@ -38,101 +38,30 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: esx hostname cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); return 1; } - if (defined($options{arguments}->{disconnect_status}) && - $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); - return 1; - } - if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); - return 1; - } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); - $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); -} - sub run { my $self = shift; - - if ($self->{connector}->{module_date_parse_loaded} == 0) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Need to install Date::Parse Perl Module."); - return ; - } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); my @properties = ('name', 'runtime.bootTime', 'runtime.connectionState'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - if (scalar(@$result) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All uptimes are ok")); - } - + my $data = {}; foreach my $entity_view (@$result) { - next if (centreon::vmware::common::host_state(connector => $self->{connector}, - hostname => $entity_view->{name}, - state => $entity_view->{'runtime.connectionState'}->val, - status => $self->{disconnect_status}, - multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); - my $create_time = Date::Parse::str2time($entity_view->{'runtime.bootTime'}); - if (!defined($create_time)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't Parse date '" . $entity_view->{'runtime.bootTime'} . "'"); - return ; - } - - my $diff_time = time() - $create_time; - my $days = int($diff_time / 60 / 60 / 24); - - my $exit = $self->{manager}->{perfdata}->threshold_check(value => $diff_time, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Uptime: %s day(s)", - $entity_view->{name}, - $days)); - if ($multiple == 0 || - !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => sprintf("'%s' Uptime: %s day(s)", - $entity_view->{name}, - $days)); - } - - my $extra_label = ''; - $extra_label = '_' . $entity_view->{name} if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => 'uptime' . $extra_label, unit => 's', - value => $diff_time, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $data->{$entity_value}->{boot_time} = $entity_view->{'runtime.bootTime'}; } + + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm index 28909261b..2e51a0c55 100644 --- a/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvmoperationcluster.pm @@ -23,8 +23,6 @@ use base qw(centreon::vmware::cmdbase); use strict; use warnings; use centreon::vmware::common; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); sub new { my ($class, %options) = @_; @@ -40,60 +38,25 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{cluster}) && $options{arguments}->{cluster} eq "") { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: cluster cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: cluster cannot be null"); return 1; } - foreach my $label (('warning_svmotion', 'critical_svmotion', 'warning_vmotion', 'critical_vmotion', - 'warning_clone', 'critical_clone')) { - if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { - $options{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); - return 1; - } - } return 0; } -sub initArgs { - my ($self, %options) = @_; - - foreach (keys %{$options{arguments}}) { - $self->{$_} = $options{arguments}->{$_}; - } - $self->{manager} = centreon::vmware::common::init_response(); - $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; - foreach my $label (('warning_svmotion', 'critical_svmotion', 'warning_vmotion', 'critical_vmotion', - 'warning_clone', 'critical_clone')) { - $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); - } -} - sub run { my $self = shift; - - $self->{statefile_cache} = centreon::plugins::statefile->new(output => $self->{manager}->{output}); - $self->{statefile_cache}->read(statefile_dir => $self->{connector}->{retention_dir}, - statefile => "cache_vmware_connector_" . $self->{connector}->{whoaim} . "_" . $self->{commandName} . "_" . (defined($self->{cluster}) ? md5_hex($self->{cluster}) : md5_hex('.*')), - statefile_suffix => '', - no_quit => 1); - return if ($self->{statefile_cache}->error() == 1); if (!($self->{connector}->{perfcounter_speriod} > 0)) { - $self->{manager}->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't retrieve perf counters"); + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); return ; } - my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'cluster', is_regexp => 'filter'); my @properties = ('name'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); return if (!defined($result)); - - if (scalar(@$result) > 1) { - $multiple = 1; - } + my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, $result, [{'label' => 'vmop.numVMotion.latest', 'instances' => ['']}, @@ -103,71 +66,17 @@ sub run { sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - - if ($multiple == 1) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("All virtual machine operations are ok")); - } - - my $new_datas = {}; - my $old_datas = {}; - my $checked = 0; + + my $data = {}; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - my $name = centreon::vmware::common::substitute_name(value => $entity_view->{name}); - my %values = (); - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - - foreach my $label (('Clone', 'VMotion', 'SVMotion')) { - $new_datas->{$label . '_' . $entity_value} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.num' . $label . '.latest'}->{key} . ":"}; - $old_datas->{$label . '_' . $entity_value} = $self->{statefile_cache}->get(name => $label . '_' . $entity_value); - - next if (!defined($old_datas->{$label . '_' . $entity_value})); - $checked = 1; - - if ($old_datas->{$label . '_' . $entity_value} > $new_datas->{$label . '_' . $entity_value}) { - $old_datas->{$label . '_' . $entity_value} = 0; - } - - my $diff = $new_datas->{$label . '_' . $entity_value} - $old_datas->{$label . '_' . $entity_value}; - $long_msg .= $long_msg_append . $label . ' ' . $diff; - $long_msg_append = ', '; - - my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $diff, threshold => [ { label => 'critical_' . lc($label), exit_litteral => 'critical' }, { label => 'warning_' . lc($label), exit_litteral => 'warning' } ]); - push @exits, $exit2; - if ($multiple == 0 || !$self->{manager}->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $label . ' ' . $diff; - $short_msg_append = ', '; - } - - my $extra_label = ''; - $extra_label = '_' . $name if ($multiple == 1); - $self->{manager}->{output}->perfdata_add(label => lc($label) . $extra_label, - value => $diff, - warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning_' . lc($label)), - critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical_' . lc($label)), - min => 0); - } - - $self->{manager}->{output}->output_add(long_msg => "Cluster '" . $name . "' vm operations: $long_msg"); - my $exit = $self->{manager}->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{manager}->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{manager}->{output}->output_add(severity => $exit, - short_msg => "Cluster '" . $name . "' vm operations: $short_msg" - ); - } - - if ($multiple == 0) { - $self->{manager}->{output}->output_add(short_msg => "Cluster '" . $name . "' vm operations: $long_msg"); - } + $data->{$entity_value} = { name => centreon::vmware::common::substitute_name(value => $entity_view->{name}) }; + $data->{$entity_value}->{'vmop.numVMotion.latest'} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.numVMotion.latest'}->{key} . ":"}; + $data->{$entity_value}->{'vmop.numSVMotion.latest'} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.numSVMotion.latest'}->{key} . ":"}; + $data->{$entity_value}->{'vmop.numClone.latest'} = $values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'vmop.numClone.latest'}->{key} . ":"}; } - if ($checked == 0) { - $self->{manager}->{output}->output_add(severity => 'OK', - short_msg => sprintf("Buffer creation")); - } - $self->{statefile_cache}->write(data => $new_datas); + centreon::vmware::common::set_response(data => $data); } 1; diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 976f2e3be..dffaa2ae2 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -590,80 +590,12 @@ sub is_running { return 1; } -sub datastore_state { - my (%options) = @_; - my $status = defined($options{status}) ? $options{status} : $options{connector}->{datastore_state_error}; - - if ($options{state} !~ /^true|1$/) { - my $output = "Datastore '" . $options{name} . "' not accessible. Current connection state: '$options{state}'."; - if ($options{multiple} == 0 || - !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { - $manager_display->{output}->output_add(severity => $status, - short_msg => $output); - } - return 0; - } - - return 1; -} - -sub vm_state { - my (%options) = @_; - my $status = defined($options{status}) ? $options{status} : $options{connector}->{host_state_error}; - my $power_status = defined($options{powerstatus}) ? $options{powerstatus} : $options{connector}->{vm_state_error}; - - if ($options{state} !~ /^connected$/i) { - my $output = "VM '" . $options{hostname} . "' not connected. Current Connection State: '$options{state}'."; - if ($options{multiple} == 0 || - !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { - $manager_display->{output}->output_add(severity => $status, - short_msg => $output); - } - return 0; - } - - if (!defined($options{nocheck_ps}) && $options{power} !~ /^poweredOn$/i) { - my $output = "VM '" . $options{hostname} . "' not running. Current Power State: '$options{power}'."; - if ($options{multiple} == 0 || - !$manager_display->{output}->is_status(value => $power_status, compare => 'ok', litteral => 1)) { - $manager_display->{output}->output_add(severity => $power_status, - short_msg => $output); - } - return 0; - } - - return 1; -} - -sub host_state { - my (%options) = @_; - my $status = defined($options{status}) ? $options{status} : $options{connector}->{host_state_error}; - - if ($options{state} !~ /^connected$/i) { - my $output = "Host '" . $options{hostname} . "' not connected. Current Connection State: '$options{state}'."; - if ($options{multiple} == 0 || - !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { - $manager_display->{output}->output_add(severity => $status, - short_msg => $output); - } - return 0; - } - - return 1; -} - -sub host_maintenance { +sub is_maintenance { my (%options) = @_; if ($options{maintenance} =~ /^true|1$/) { - my $output = "Host '" . $options{hostname} . "' is in maintenance mode."; - if ($options{multiple} == 0) { - $manager_display->{output}->output_add(severity => 'OK', - short_msg => $output); - } return 0; } - return 1; } diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 76448ff19..b0503b973 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -55,7 +55,6 @@ sub new { $connector->{modules_registry} = $options{modules_registry}; $connector->{logger} = $options{logger}; $connector->{whoaim} = $options{name}; - $connector->{module_date_parse_loaded} = $options{module_date_parse_loaded}; $connector->{config_child_timeout} = $options{config}->{timeout}; $connector->{config_stop_child_timeout} = $options{config}->{timeout_kill}; $connector->{config_vsphere_session_heartbeat} = $options{config}->{refresh_keeper_session}; @@ -63,10 +62,6 @@ sub new { $connector->{config_vsphere_url} = $options{config}->{vsphere_server}->{$options{name}}->{url}; $connector->{config_vsphere_user} = $options{config}->{vsphere_server}->{$options{name}}->{username}; $connector->{config_vsphere_pass} = $options{config}->{vsphere_server}->{$options{name}}->{password}; - $connector->{retention_dir} = $options{config}->{retention_dir}; - $connector->{datastore_state_error} = $options{config}->{datastore_state_error}; - $connector->{vm_state_error} = $options{config}->{vm_state_error}; - $connector->{host_state_error} = $options{config}->{host_state_error}; return $connector; } From dd81333233b2effe8640f52299c3500bfdbd2e5c Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 31 Jan 2019 13:15:24 +0100 Subject: [PATCH 197/447] WIP: centreon-vmware 3.0.0 --- .../vmware/src/centreon/script/centreon_vmware.pm | 11 +++-------- connectors/vmware/src/centreon/vmware/connector.pm | 1 - .../vmware/src/centreon/{common => vmware}/logger.pm | 6 +++--- connectors/vmware/src/centreon/{ => vmware}/script.pm | 6 +++--- 4 files changed, 9 insertions(+), 15 deletions(-) rename connectors/vmware/src/centreon/{common => vmware}/logger.pm (97%) rename connectors/vmware/src/centreon/{ => vmware}/script.pm (94%) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index b10e152ed..c5ebc78e2 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -29,7 +29,7 @@ use File::Basename; use Digest::MD5 qw(md5_hex); use POSIX ":sys_wait_h"; use JSON::XS; -use centreon::script; +use centreon::vmware::script; use centreon::vmware::common; use centreon::vmware::connector; @@ -51,7 +51,7 @@ BEGIN { }; } -use base qw(centreon::script); +use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); my $VERSION = "3.0.0"; @@ -98,12 +98,7 @@ my @load_modules = ( sub new { my $class = shift; - my $self = $class->SUPER::new("centreon_vmware", - # we keep it if we use centreon common library - centreon_db_conn => 0, - centstorage_db_conn => 0, - noconfig => 1 - ); + my $self = $class->SUPER::new("centreon_vmware"); bless $self, $class; $self->add_options( diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index b0503b973..f559ac9e7 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -26,7 +26,6 @@ use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); use File::Basename; use POSIX ":sys_wait_h"; -use centreon::script; use centreon::vmware::common; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); diff --git a/connectors/vmware/src/centreon/common/logger.pm b/connectors/vmware/src/centreon/vmware/logger.pm similarity index 97% rename from connectors/vmware/src/centreon/common/logger.pm rename to connectors/vmware/src/centreon/vmware/logger.pm index 1f726c128..ab59dad93 100644 --- a/connectors/vmware/src/centreon/common/logger.pm +++ b/connectors/vmware/src/centreon/vmware/logger.pm @@ -16,11 +16,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -package centreon::common::logger; +package centreon::vmware::logger; =head1 NOM -centreon::common::logger - Simple logging module +centreon::vmware::logger - Simple logging module =head1 SYNOPSIS @@ -31,7 +31,7 @@ centreon::common::logger - Simple logging module use centreon::polling; - my $logger = new centreon::common::logger(); + my $logger = new centreon::vmware::logger(); $logger->writeLogInfo("information"); diff --git a/connectors/vmware/src/centreon/script.pm b/connectors/vmware/src/centreon/vmware/script.pm similarity index 94% rename from connectors/vmware/src/centreon/script.pm rename to connectors/vmware/src/centreon/vmware/script.pm index 5f83dc1c4..b1b9aa8c6 100644 --- a/connectors/vmware/src/centreon/script.pm +++ b/connectors/vmware/src/centreon/vmware/script.pm @@ -16,14 +16,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -package centreon::script; +package centreon::vmware::script; use strict; use warnings; use FindBin; use Getopt::Long; use Pod::Usage; -use centreon::common::logger; +use centreon::vmware::logger; $SIG{__DIE__} = sub { return unless defined $^S and $^S == 0; # Ignore errors in eval @@ -44,7 +44,7 @@ sub new { bless $self, $class; $self->{name} = $name; - $self->{logger} = centreon::common::logger->new(); + $self->{logger} = centreon::vmware::logger->new(); $self->{options} = { "logfile=s" => \$self->{log_file}, "severity=s" => \$self->{severity}, From f32ecf4689ed7c2ca9068e611d43d086c47bfcc8 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 1 Feb 2019 14:30:23 +0100 Subject: [PATCH 198/447] update countvm --- connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm index dedd1b313..75640d781 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcountvmhost.pm @@ -68,7 +68,8 @@ sub run { my $data = {}; foreach my $entity_view (@$result) { - $data->{$entity_view->{name}} = { state => $entity_view->{'runtime.connectionState'}->val }; + my $entity_value = $entity_view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $entity_view->{name}, state => $entity_view->{'runtime.connectionState'}->val }; next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); my %vm_states = (poweredon => 0, poweredoff => 0, suspended => 0); @@ -84,7 +85,7 @@ sub run { } } - $data->{$entity_view->{name}} = { %{$data->{$entity_view->{name}}}, %vm_states }; + $data->{$entity_value} = { %{$data->{$entity_value}}, %vm_states }; } centreon::vmware::common::set_response(data => $data); From 5e642ab5be388828d5375a191f73c42fce1d5ba6 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 4 Feb 2019 08:47:27 +0100 Subject: [PATCH 199/447] change datastore return state name --- connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm | 2 +- connectors/vmware/src/centreon/vmware/cmddatastoreio.pm | 2 +- connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm | 2 +- connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm | 2 +- connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm index 0c2d70b5e..97734b494 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorecountvm.pm @@ -66,7 +66,7 @@ sub run { my $data = {}; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - $data->{$entity_value} = { name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'} }; + $data->{$entity_value} = { name => $entity_view->{'summary.name'}, accessible => $entity_view->{'summary.accessible'} }; next if (centreon::vmware::common::is_accessible(accessible => $entity_view->{'summary.accessible'}) == 0); my %vm_states = (poweredon => 0, poweredoff => 0, suspended => 0); diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm index 1462da448..27cb1fcdd 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreio.pm @@ -71,7 +71,7 @@ sub run { foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - $data->{$entity_value} = { name => $entity_view->{'summary.name'}, state => $entity_view->{'summary.accessible'} }; + $data->{$entity_value} = { name => $entity_view->{'summary.name'}, accessible => $entity_view->{'summary.accessible'} }; next if (centreon::vmware::common::is_accessible(accessible => $entity_view->{'summary.accessible'}) == 0); # in KBps diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 0093f6c04..c1f3133c1 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -64,7 +64,7 @@ sub run { my %datastore_lun = (); my $ds_checked = 0; foreach (@$result) { - $data->{$_->{'summary.name'}} = { name => $_->{'summary.name'}, state => $_->{'summary.accessible'} }; + $data->{$_->{'summary.name'}} = { name => $_->{'summary.name'}, accessible => $_->{'summary.accessible'} }; next if (centreon::vmware::common::is_accessible(accessible => $_->{'summary.accessible'}) == 0); if ($_->info->isa('VmfsDatastoreInfo')) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm index 7a47a7f83..c0e561b9c 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoresnapshot.pm @@ -59,7 +59,7 @@ sub run { my $entity_value = $entity_view->{mo_ref}->{value}; $data->{$entity_value} = { name => $entity_view->{'summary.name'}, - state => $entity_view->{'summary.accessible'}, + accessible => $entity_view->{'summary.accessible'}, error_message => '', snapshost => [], }; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index fe78d9379..c51d6b63b 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -59,7 +59,7 @@ sub run { foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - $data->{$entity_value} = { name => $entity_view->summary->name, state => $entity_view->summary->accessible }; + $data->{$entity_value} = { name => $entity_view->summary->name, accessible => $entity_view->summary->accessible }; next if (centreon::vmware::common::is_accessible(accessible => $entity_view->summary->accessible) == 0); # capacity 0... From c4af74bab5d0e6c47fd2e7b3ac8515ac9cee9d12 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 4 Feb 2019 11:02:01 +0100 Subject: [PATCH 200/447] correct cpu vm --- connectors/vmware/src/centreon/vmware/cmdcpuvm.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 806dedd4a..14923057d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -113,9 +113,9 @@ sub run { $cib = -1 if (!defined($cib) || $cib eq ""); $cia <=> $cib} keys %{$values->{$entity_value}}) { my ($counter_id, $instance) = split /:/, $id; - next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); + next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} == $counter_id); if ($instance ne "") { - $data->{$entity_value}->{cpu}->{$instance} = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id})); + $data->{$entity_value}->{cpu}->{$instance} = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id} * 0.01)); } } } From 8b1c27b659430256c887c8dea6f4c85c4c41c347 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 4 Feb 2019 11:08:02 +0100 Subject: [PATCH 201/447] correct cpu vm --- connectors/vmware/src/centreon/vmware/cmdcpuvm.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 14923057d..806dedd4a 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -113,9 +113,9 @@ sub run { $cib = -1 if (!defined($cib) || $cib eq ""); $cia <=> $cib} keys %{$values->{$entity_value}}) { my ($counter_id, $instance) = split /:/, $id; - next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} == $counter_id); + next if ($self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} != $counter_id); if ($instance ne "") { - $data->{$entity_value}->{cpu}->{$instance} = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id} * 0.01)); + $data->{$entity_value}->{cpu}->{$instance} = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$id})); } } } From 7eb7e05b0abafc69879ea41666c3eb4f3b3ba0c3 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 4 Feb 2019 15:07:20 +0100 Subject: [PATCH 202/447] fix and remove debug --- connectors/vmware/src/centreon/vmware/cmddevicevm.pm | 2 +- connectors/vmware/src/centreon/vmware/cmdlimitvm.pm | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm index 470e382c4..5da39a60b 100644 --- a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm @@ -83,7 +83,7 @@ sub run { foreach my $dev (@{$entity_view->{'config.hardware.device'}}) { if (ref($dev) =~ /$self->{device}/) { - if ($dev->connectable->connected == 1) { + if (defined($dev->connectable) && $dev->connectable->connected == 1) { $data->{$entity_value}->{total_device_connected}++; } } diff --git a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index ab6eeeaa3..6904bdb3d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -92,8 +92,6 @@ sub run { # Disk if (defined($self->{check_disk_limit})) { - use Data::Dumper; - print Data::Dumper::Dumper($entity_view->{'config.hardware.device'}); foreach my $device (@{$entity_view->{'config.hardware.device'}}) { if ($device->isa('VirtualDisk')) { if (defined($device->storageIOAllocation->limit) && $device->storageIOAllocation->limit != -1) { From 9ce4483bf16396ccccd8370aec38fa885a28ebf2 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 5 Feb 2019 09:22:17 +0100 Subject: [PATCH 203/447] add state value --- connectors/vmware/src/centreon/vmware/cmdmemhost.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm index 9aa7e9021..c7c72c80b 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemhost.pm @@ -97,7 +97,8 @@ sub run { $data->{$entity_value}->{mem_size} = $memory_size; $data->{$entity_value}->{'mem.consumed.average'} = $mem_used; $data->{$entity_value}->{'mem.overhead.average'} = $mem_overhead; - $data->{$entity_value}->{mem_state} = defined($mem_state) ? $mapping_state{$mem_state} : undef; + $data->{$entity_value}->{mem_state_str} = defined($mem_state) ? $mapping_state{$mem_state} : undef; + $data->{$entity_value}->{mem_state} = defined($mem_state) ? $mem_state : undef; } centreon::vmware::common::set_response(data => $data); From f50680278d708c147f0ee8f4aa78f00c40411336 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 5 Feb 2019 12:42:05 +0100 Subject: [PATCH 204/447] add key in service return --- connectors/vmware/src/centreon/vmware/cmdservicehost.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm index eea7607e0..992b88c98 100644 --- a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm @@ -87,7 +87,7 @@ sub run { my $hostname = $host_names{$entity->{mo_ref}->{value}}; foreach my $service (@{$entity->{serviceInfo}->{service}}) { - push @{$data->{$entity->{mo_ref}->{value}}->{services}}, { label => $service->{label}, policy => $service->{policy}, running => $service->{running} }; + push @{$data->{$entity->{mo_ref}->{value}}->{services}}, { key => $service->{key}, label => $service->{label}, policy => $service->{policy}, running => $service->{running} }; } } From 1df4d636c85b77a9035ddf5f9bcb824a46499673 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 5 Feb 2019 12:46:37 +0100 Subject: [PATCH 205/447] fix servicehost --- connectors/vmware/src/centreon/vmware/cmdservicehost.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm index 992b88c98..0c50e7d2e 100644 --- a/connectors/vmware/src/centreon/vmware/cmdservicehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdservicehost.pm @@ -70,7 +70,7 @@ sub run { if (defined($entity_view->{'configManager.serviceSystem'})) { push @host_array, $entity_view->{'configManager.serviceSystem'}; - $host_names{$entity_view->{'configManager.serviceSystem'}->{value}} = $entity_view->{name}; + $host_names{$entity_view->{'configManager.serviceSystem'}->{value}} = $entity_value; } } @@ -84,10 +84,10 @@ sub run { return if (!defined($result2)); foreach my $entity (@$result2) { - my $hostname = $host_names{$entity->{mo_ref}->{value}}; + my $host_id = $host_names{$entity->{mo_ref}->{value}}; foreach my $service (@{$entity->{serviceInfo}->{service}}) { - push @{$data->{$entity->{mo_ref}->{value}}->{services}}, { key => $service->{key}, label => $service->{label}, policy => $service->{policy}, running => $service->{running} }; + push @{$data->{$host_id}->{services}}, { key => $service->{key}, label => $service->{label}, policy => $service->{policy}, running => $service->{running} }; } } From 6acc6fb08e2643380ffbff8071da541a11ccf925 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 5 Feb 2019 15:31:00 +0100 Subject: [PATCH 206/447] wip: documentation update --- .../vmware/doc/en/installation/index.rst | 38 +++---------------- .../vmware/doc/fr/installation/index.rst | 34 ++--------------- 2 files changed, 8 insertions(+), 64 deletions(-) diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 2732b7ee9..5356b5e3f 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -126,21 +126,12 @@ Configure "centreon-vmware" daemon to start at boot: :: # update-rc.d centreon_vmware defaults - -Install « perl-centreon-base » dependency: -:: - - # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon - # cd centreon - # cp lib/perl/centreon/script.pm /usr/share/perl5/centreon/ - # cp -R lib/perl/centreon/common /usr/share/perl5/centreon/ Install the client and dependency: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins - # cp -R centreon/plugins /usr/share/perl5/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ @@ -177,7 +168,6 @@ Requirements Following prerequisites are mandatory for « centreon_vmware »: -* « perl-centreon-base »: module since Centreon 2.5 (repository ces standard) * « centreon-plugins-base »: in repository ces standard * « zeromq » and Perl binding: in repository ces standard or EPEL @@ -204,8 +194,8 @@ centreon-vmware Installation with source Download « centreon-vmware » archive, then install: :: - # tar zxvf centreon-vmware-2.0.0.tar.gz - # cd centreon-vmware-2.0.0 + # tar zxvf centreon-vmware-3.0.0.tar.gz + # cd centreon-vmware-3.0.0 # cp centreon_vmware.pl /usr/bin/ # mkdir -p /etc/centreon @@ -222,21 +212,12 @@ Configure "centreon-vmware" daemon to start at boot: :: # chkconfig --level 2345 centreon_vmware on - -Install « perl-centreon-base » dependency: -:: - - # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon - # cd centreon - # cp lib/perl/centreon/script.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/ - # cp -R lib/perl/centreon/common /usr/lib/perl5/vendor_perl/5.8.8/centreon/ Install the client and dependency: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins - # cp -R centreon/plugins /usr/lib/perl5/vendor_perl/5.8.8/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ @@ -292,7 +273,7 @@ Install the connector: Install the client: :: - # yum install centreon-plugin-Virtualization-VMWare-client + # yum install centreon-plugin-Virtualization-Vmware2-Connector-Plugin centreon-vmware Installation with source ```````````````````````````````````````` @@ -300,8 +281,8 @@ centreon-vmware Installation with source Download « centreon-vmware » archive, then install: :: - # tar zxvf centreon-vmware-2.0.0.tar.gz - # cd centreon-vmware-2.0.0 + # tar zxvf centreon-vmware-3.0.0.tar.gz + # cd centreon-vmware-3.0.0 # cp centreon_vmware.pl /usr/bin/ # mkdir -p /etc/centreon @@ -318,21 +299,12 @@ Configure "centreon-vmware" daemon to start at boot: :: # chkconfig --level 2345 centreon_vmware on - -Install « perl-centreon-base » dependency: -:: - - # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon - # cd centreon - # cp lib/perl/centreon/script.pm /usr/share/perl5/vendor_perl/centreon/ - # cp -R lib/perl/centreon/common /usr/share/perl5/vendor_perl/centreon/ Install the client and dependency: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins - # cp -R centreon/plugins /usr/share/perl5/vendor_perl/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index 38ac826f2..b84d9a6c4 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -71,7 +71,6 @@ Pré-requis Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_vmware »: -* « perl-centreon-base »: module depuis Centreon 2.5 * « centreon-plugins-base »: le client et des dépendances * « zeromq » et son module Perl @@ -126,14 +125,6 @@ Activer le daemon « centreon-vmware » au démarrage: :: # update-rc.d centreon_vmware defaults - -Installer la dépendance « perl-centreon-base »: -:: - - # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon - # cd centreon - # cp lib/perl/centreon/script.pm /usr/share/perl5/centreon/ - # cp -R lib/perl/centreon/common /usr/share/perl5/centreon/ Installer le client et les dépendances: :: @@ -177,7 +168,6 @@ Pré-requis Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_vmware »: -* « perl-centreon-base »: module depuis Centreon 2.5 (dépôt ces standard) * « centreon-plugins-base »: dépôt ces standard * « zeromq » and Perl binding: dépôt ces standard ou EPEL @@ -191,12 +181,12 @@ Installation de centreon-vmware par rpm Installer le connecteur: :: - # yum install ces-plugins-Virtualization-VMWare-daemon + # yum install centreon-plugin-Virtualization-VMWare-daemon Installer le client: :: - # yum install ces-plugins-Virtualization-VMWare-client + # yum install centreon-plugin-Virtualization-Vmware2-Connector-Plugin Installation de centreon-vmware par les sources ``````````````````````````````````````````````` @@ -224,21 +214,12 @@ Activer le daemon « centreon-vmware » au démarrage: :: # chkconfig --level 2345 centreon_vmware on - -Installer la dépendance « perl-centreon-base »: -:: - - # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon - # cd centreon - # cp lib/perl/centreon/script.pm /usr/lib/perl5/vendor_perl/5.8.8/centreon/ - # cp -R lib/perl/centreon/common /usr/lib/perl5/vendor_perl/5.8.8/centreon/ Installer le client et les dépendances: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins - # cp -R centreon/plugins /usr/lib/perl5/vendor_perl/5.8.8/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ @@ -323,22 +304,13 @@ Activer le daemon « centreon-vmware » au démarrage: # chkconfig --level 2345 centreon_vmware on -Installer la dépendance « perl-centreon-base »: -:: - - # git clone -b 2.6.x --single-branch https://github.com/centreon/centreon.git centreon - # cd centreon - # cp lib/perl/centreon/script.pm /usr/share/perl5/vendor_perl/centreon/ - # cp -R lib/perl/centreon/common /usr/share/perl5/vendor_perl/centreon/ - Installer le client et les dépendances: :: # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins - # cp -R centreon/plugins /usr/share/perl5/vendor_perl/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ - # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ + # cp -R centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ # cp -R apps/vmware/* /usr/lib/nagios/plugins/apps/vmware/ # cp centreon_plugins.pl /usr/lib/nagios/plugins/ From 4d8c819c106dfb81f75a433ba624a6eaee39daad Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 5 Feb 2019 17:59:41 +0100 Subject: [PATCH 207/447] update install doc for debian stretch --- .../vmware/doc/en/installation/index.rst | 55 ++++++++----------- .../vmware/doc/fr/installation/index.rst | 53 ++++++++---------- .../packaging/debian/centreon_vmware-systemd | 27 +++++++++ 3 files changed, 72 insertions(+), 63 deletions(-) create mode 100644 connectors/vmware/packaging/debian/centreon_vmware-systemd diff --git a/connectors/vmware/doc/en/installation/index.rst b/connectors/vmware/doc/en/installation/index.rst index 5356b5e3f..d95e82c32 100644 --- a/connectors/vmware/doc/en/installation/index.rst +++ b/connectors/vmware/doc/en/installation/index.rst @@ -19,7 +19,7 @@ Perl 5.8 centreon-vmware 2.0.0 perl-centreon-base 2.6.0 centreon-plugins-base 1.11 -ZeroMQ 3.x +ZeroMQ 4.x Perl Date::Parse 1.x Perl ZMQ::LibZMQ4 0.01 Perl ZMQ::Constants 1.04 @@ -35,8 +35,8 @@ Hardware prerequisites will depend of check numbers. Minimal used resources are * RAM : 512 Mo (May slightly increase with the number of checks). * CPU : same as poller server. -Centreon-vmware Installation - Debian Wheezy -============================================ +Centreon-vmware Installation - Debian Stretch +============================================= SDK Perl VMWare Installation ```````````````````````````` @@ -46,23 +46,23 @@ The "centreon-vmware" connector uses SDK Perl VMWare for its operation. So we in ========================== ===================== ====================== Dependency Version Repository ========================== ===================== ====================== -libwww-perl 6.04 wheezy -libxml-libxml-perl 2.0001 wheezy -libclass-methodmaker-perl 2.18 wheezy -libcrypt-ssleay-perl 0.58 wheezy -libsoap-lite-perl 0.714 wheezy -libuuid-perl 0.02 wheezy +libwww-perl 6.15 stretch +libxml-libxml-perl 2.0128 stretch +libclass-methodmaker-perl 2.24 stretch +libcrypt-ssleay-perl 0.73 stretch +libsoap-lite-perl 1.20 stretch +libuuid-perl 0.27 stretch ========================== ===================== ====================== Install following dependency: :: - # aptitude install make libxml-libxml-perl libwww-perl libclass-methodmaker-perl libcrypt-ssleay-perl libsoap-lite-perl libuuid-perl + # apt-get install make libxml-libxml-perl libwww-perl libclass-methodmaker-perl libcrypt-ssleay-perl libsoap-lite-perl libuuid-perl libtext-template-perl Download the Perl SDK VMWare and install it: :: - # tar zxf VMware-vSphere-Perl-SDK-6.0.0-2503617.x86_64.tar.gz && cd vmware-vsphere-cli-distrib + # tar zxf VMware-vSphere-Perl-SDK-6.7.0-8156551.x86_64.tar.gz && cd vmware-vsphere-cli-distrib # perl Makefile.PL # make && make install @@ -71,31 +71,20 @@ Requirements Following prerequisites are mandatory for « centreon_vmware »: -* « perl-centreon-base »: module since Centreon 2.5 -* « centreon-plugins-base »: the client and some dependencies * « zeromq » and Perl binding -Following prerequisites are optional for « centreon_vmware »: - -* « libtimedate-perl » - centreon-vmware Installation with source ```````````````````````````````````````` Install the following package: :: - # aptitude install libtimedate-perl + # aptitude install libzmq5 -Add the following line in « /etc/apt/sources.list » file: +Install « zeromq » perl binding dependency (need to patch the installer: https://rt.cpan.org/Public/Bug/Display.html?id=122932): :: - deb http://http.debian.net/debian wheezy-backports main - -Install « zeromq » dependency: -:: - - # aptitude install libzmq4-dev gcc + # apt-get install gcc libmodule-install-perl libzmq3-dev # wget https://github.com/lestrrat/p5-ZMQ/archive/master.zip # unzip master.zip # cd p5-ZMQ-master/ZMQ-LibZMQ4/ @@ -108,15 +97,16 @@ Install « zeromq » dependency: Download « centreon-vmware » archive, then install: :: - # tar zxvf centreon-vmware-2.0.0.tar.gz - # cd centreon-vmware-2.0.0 + # tar zxvf centreon-vmware-3.0.0.tar.gz + # cd centreon-vmware-3.0.0 # cp centreon_vmware.pl /usr/bin/ - # mkdir -p /etc/centreon + # mkdir -p /etc/centreon /var/log/centreon + # useradd centreon + # chown centreon:centreon /var/log/centreon # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm - # cp contrib/debian/centreon_vmware-init /etc/init.d/centreon_vmware - # cp contrib/debian/centreon_vmware-default /etc/default/centreon_vmware - # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl + # cp contrib/debian/centreon_vmware-systemd /lib/systemd/system/centreon_vmware.service + # chmod 664 /lib/systemd/system/centreon_vmware.service # mkdir -p /usr/share/perl5/centreon/vmware/ /usr/share/perl5/centreon/script/ # cp centreon/vmware/* /usr/share/perl5/centreon/vmware/ @@ -125,11 +115,12 @@ Download « centreon-vmware » archive, then install: Configure "centreon-vmware" daemon to start at boot: :: - # update-rc.d centreon_vmware defaults + # systemctl enable centreon_vmware.service Install the client and dependency: :: + # apt-get install libtimedate-perl # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ diff --git a/connectors/vmware/doc/fr/installation/index.rst b/connectors/vmware/doc/fr/installation/index.rst index b84d9a6c4..fceb4399d 100644 --- a/connectors/vmware/doc/fr/installation/index.rst +++ b/connectors/vmware/doc/fr/installation/index.rst @@ -19,7 +19,7 @@ Perl 5.8 centreon-vmware 2.0.0 perl-centreon-base 2.5.0 centreon-plugins-base 1.10 -ZeroMQ 3.x +ZeroMQ 4.x Perl Date::Parse 1.x Perl ZMQ::LibZMQ4 0.01 Perl ZMQ::Constants 1.04 @@ -46,23 +46,23 @@ Le connecteur « centreon-vmware » utilise le SDK Perl VMWare pour son foncti ========================== ===================== ====================== Dependency Version Repository ========================== ===================== ====================== -libwww-perl 6.04 wheezy -libxml-libxml-perl 2.0001 wheezy -libclass-methodmaker-perl 2.18 wheezy -libcrypt-ssleay-perl 0.58 wheezy -libsoap-lite-perl 0.714 wheezy -libuuid-perl 0.02 wheezy +libwww-perl 6.15 stretch +libxml-libxml-perl 2.0128 stretch +libclass-methodmaker-perl 2.24 stretch +libcrypt-ssleay-perl 0.73 stretch +libsoap-lite-perl 1.20 stretch +libuuid-perl 0.27 stretch ========================== ===================== ====================== Installer les dépendances suivantes: :: - # aptitude install make libxml-libxml-perl libwww-perl libclass-methodmaker-perl libcrypt-ssleay-perl libsoap-lite-perl libuuid-perl - + # apt-get install make libxml-libxml-perl libwww-perl libclass-methodmaker-perl libcrypt-ssleay-perl libsoap-lite-perl libuuid-perl libtext-template-perl + Télécharger et installer le Perl SDK VMWare: :: - # tar zxf VMware-vSphere-Perl-SDK-6.0.0-2503617.x86_64.tar.gz && cd vmware-vsphere-cli-distrib + # tar zxf VMware-vSphere-Perl-SDK-6.7.0-8156551.x86_64.tar.gz && cd vmware-vsphere-cli-distrib # perl Makefile.PL # make && make install @@ -71,30 +71,20 @@ Pré-requis Les dépendances suivantes sont nécessaires pour le fonctionnement de « centreon_vmware »: -* « centreon-plugins-base »: le client et des dépendances * « zeromq » et son module Perl -Les dépendances suivantes sont optionnelles pour le fonctionnement de « centreon_vmware »: - -* « libtimedate-perl » - Installation de centreon-vmware par les sources ``````````````````````````````````````````````` Installer le paquet suivant: :: - # aptitude install libtimedate-perl + # apt-get install libzmq5 -Ajouter la ligne suivante dans le fichier « /etc/apt/sources.list »: +Installer le perl binding « zeromq » (nécessite l'application du patch: https://rt.cpan.org/Public/Bug/Display.html?id=122932): :: - deb http://http.debian.net/debian wheezy-backports main - -Installer la dépendance « zeromq »: -:: - - # aptitude install libzmq4-dev gcc + # apt-get install gcc libmodule-install-perl libzmq3-dev # wget https://github.com/lestrrat/p5-ZMQ/archive/master.zip # unzip master.zip # cd p5-ZMQ-master/ZMQ-LibZMQ4/ @@ -107,15 +97,16 @@ Installer la dépendance « zeromq »: Télécharger l'archive de « centreon-vmware » et installer le connecteur: :: - # tar zxvf centreon-vmware-2.0.0.tar.gz - # cd centreon-vmware-2.0.0 + # tar zxvf centreon-vmware-3.0.0.tar.gz + # cd centreon-vmware-3.0.0 # cp centreon_vmware.pl /usr/bin/ - # mkdir -p /etc/centreon + # mkdir -p /etc/centreon /var/log/centreon + # useradd centreon + # chown centreon:centreon /var/log/centreon # cp contrib/config/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm - # cp contrib/debian/centreon_vmware-init /etc/init.d/centreon_vmware - # cp contrib/debian/centreon_vmware-default /etc/default/centreon_vmware - # chmod 775 /etc/init.d/centreon_vmware /usr/bin/centreon_vmware.pl + # cp contrib/debian/centreon_vmware-systemd /lib/systemd/system/centreon_vmware.service + # chmod 664 /lib/systemd/system/centreon_vmware.service # mkdir -p /usr/share/perl5/centreon/vmware/ /usr/share/perl5/centreon/script/ # cp centreon/vmware/* /usr/share/perl5/centreon/vmware/ @@ -124,14 +115,14 @@ Télécharger l'archive de « centreon-vmware » et installer le connecteur: Activer le daemon « centreon-vmware » au démarrage: :: - # update-rc.d centreon_vmware defaults + # systemctl enable centreon_vmware.service Installer le client et les dépendances: :: + # apt-get install libtimedate-perl # git clone http://git.centreon.com/centreon-plugins.git # cd centreon-plugins - # cp -R centreon/plugins /usr/share/perl5/centreon/ # mkdir -p /usr/lib/nagios/plugins/centreon/plugins/ # cp centreon/plugins/* /usr/lib/nagios/plugins/centreon/plugins/ # mkdir -p /usr/lib/nagios/plugins/apps/vmware/ diff --git a/connectors/vmware/packaging/debian/centreon_vmware-systemd b/connectors/vmware/packaging/debian/centreon_vmware-systemd new file mode 100644 index 000000000..c0660a430 --- /dev/null +++ b/connectors/vmware/packaging/debian/centreon_vmware-systemd @@ -0,0 +1,27 @@ +## Copyright 2016 Centreon +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## +## For more information : contact@centreon.com +## + +[Unit] +Description=Centreon VMWare + +[Service] +ExecStart=/usr/bin/perl /usr/bin/centreon_vmware.pl --logfile=/var/log/centreon/centreon_vmware.log --severity=error +Type=simple +User=centreon + +[Install] +WantedBy=multi-user.target From 457d99d25aaefee09a40395160302d961b2f0ca0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 6 Feb 2019 10:58:03 +0100 Subject: [PATCH 208/447] update readme --- connectors/vmware/README.md | 45 ++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/connectors/vmware/README.md b/connectors/vmware/README.md index 8063633e7..3dff1357e 100644 --- a/connectors/vmware/README.md +++ b/connectors/vmware/README.md @@ -1,6 +1,6 @@ # centreon-vmware -“centreon-vmware” is a free and open source project. The project can be used with Centreon and all monitoring softwares compatible with Nagios plugins. +"centreon-vmware" is a free and open source project. The project can be used with Centreon and all monitoring softwares compatible with Nagios plugins. It's a Perl daemon in charged to get back VMWare indicators. This program uses the SDK Perl provided by VMWare. The connector could get following indicators: @@ -41,29 +41,38 @@ Please follow the documentation for the installation: https://github.com/centreo Check vmtools states of virtual machines (with name matching the regexp 'prd'): - $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=tools-vm --display-description --vm-hostname='prd' --filter + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --connector-hostname=127.0.0.1 --container=default --verbose --mode=tools-vm --display-description --vm-hostname='prd' --filter WARNING: 1 VM with VMTools not installed | vmtools not installed: prd-Reporting - 10.0.0.1 [description xxxx] Check datastore IOPs of virtual machines (with name matching the regexp 'centreon-central-1|Formation'): - $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=datastore-vm --vm-hostname='centreon-central-1|Formation' --filter - OK: All Datastore IOPS counters are ok | 'riops_Formation-Reporting - 10.30.2.89_R&D-BI'=0.00iops;;;0; 'wiops_Formation-Reporting - 10.30.2.89_R&D-BI'=1.43iops;;;0; 'riops_centreon-central-1_INTEGRATION'=0.00iops;;;0; 'wiops_centreon-central-1_INTEGRATION'=0.60iops;;;0; - 'Formation-Reporting - 10.30.2.89' read iops on 'R&D-BI' is 0.00 - 'Formation-Reporting - 10.30.2.89' write iops on 'R&D-BI' is 1.43 - 'centreon-central-1' read iops on 'INTEGRATION' is 0.00 - 'centreon-central-1' write iops on 'INTEGRATION' is 0.60 + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --connector-hostname=127.0.0.1 --container=default --verbose --mode=datastore-vm --vm-hostname='woot|test-migration' --filter + OK: All virtual machines are ok | 'max_total_latency_test-migration'=2.00ms;;;0; 'riops_test-migration_INTEGRATION'=0.41iops;;;0; 'wiops_test-migration_INTEGRATION'=4.84iops;;;0;4.84 'riops_test-migration_ISOs'=0.00iops;;;0; 'wiops_test-migration_ISOs'=0.00iops;;;0;0.00 'max_total_latency_woot'=23.00ms;;;0; 'riops_woot'=0.02iops;;;0; 'wiops_woot'=0.67iops;;;0;0.67 + checking virtual machine 'test-migration' + [connection state connected][power state poweredOn] + max total latency is 2.00 ms + datastore 'INTEGRATION' 0.41 read iops, 4.84 write iops + datastore 'ISOs' 0.00 read iops, 0.00 write iops + checking virtual machine 'woot' + [connection state connected][power state poweredOn] + max total latency is 23.00 ms + datastore 'DSI' 0.02 read iops, 0.67 write iops Check the health of ESX Servers: - $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --custommode=connector --connector-hostname=127.0.0.1 --container=default --verbose --mode=health-host --esx-hostname='.*' --filter --disconnect-status='ok' - OK: All ESX health checks are ok | 'problems_srvi-clus-esx-n2.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n1.merethis.net'=0;;;0;299 'problems_srvi-clus-esx-n4.merethis.net'=0;;;0;186 'problems_srvi-clus-esx-n3.merethis.net'=0;;;0;186 - Checking srvi-clus-esx-n2.merethis.net - 299 health checks are green - Checking srvi-clus-esx-n1.merethis.net - 299 health checks are green - Checking srvi-clus-esx-n4.merethis.net - 186 health checks are green - Checking srvi-clus-esx-n3.merethis.net - 186 health checks are green + $ perl centreon_plugins.pl --plugin=apps::vmware::connector::plugin --connector-hostname=127.0.0.1 --container=default --verbose --mode=health-host --esx-hostname='.*' --filter --disconnect-status='ok' + OK: 0 total health issue(s) found - All ESX hosts are ok | 'total_problems'=0;;;0;1034 'problems_srvi-clus-esx-n1.int.centreon.com'=0;;;0;315 'problems_yellow_srvi-clus-esx-n1.int.centreon.com'=0;;;0;315 'problems_red_srvi-clus-esx-n1.int.centreon.com'=0;;;0;315 'problems_srvi-clus-esx-n2.int.centreon.com'=0;;;0;315 'problems_yellow_srvi-clus-esx-n2.int.centreon.com'=0;;;0;315 'problems_red_srvi-clus-esx-n2.int.centreon.com'=0;;;0;315 'problems_srvi-clus-esx-n3.int.centreon.com'=0;;;0;202 'problems_yellow_srvi-clus-esx-n3.int.centreon.com'=0;;;0;202 'problems_red_srvi-clus-esx-n3.int.centreon.com'=0;;;0;202 'problems_srvi-clus-esx-n4.int.centreon.com'=0;;;0;202 'problems_yellow_srvi-clus-esx-n4.int.centreon.com'=0;;;0;202 'problems_red_srvi-clus-esx-n4.int.centreon.com'=0;;;0;202 + checking host 'srvi-clus-esx-n1.int.centreon.com' + status connected + 315 health checks are green, 0 total health issue(s) found, 0 yellow health issue(s) found, 0 red health issue(s) found + checking host 'srvi-clus-esx-n2.int.centreon.com' + status connected + 315 health checks are green, 0 total health issue(s) found, 0 yellow health issue(s) found, 0 red health issue(s) found + checking host 'srvi-clus-esx-n3.int.centreon.com' + status connected + 202 health checks are green, 0 total health issue(s) found, 0 yellow health issue(s) found, 0 red health issue(s) found + checking host 'srvi-clus-esx-n4.int.centreon.com' + status connected + 202 health checks are green, 0 total health issue(s) found, 0 yellow health issue(s) found, 0 red health issue(s) found From 668f6c03c35eea3eb3d7d52b556ab725032cd086 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 6 Feb 2019 11:59:48 +0100 Subject: [PATCH 209/447] add case insensitive system --- connectors/vmware/changelog | 5 +++++ .../vmware/src/centreon/vmware/cmdbase.pm | 20 +++++++++++++++++-- .../vmware/src/centreon/vmware/cmdcpuvm.pm | 5 ++--- .../src/centreon/vmware/cmddatastorevm.pm | 5 ++--- .../vmware/src/centreon/vmware/cmddevicevm.pm | 5 ++--- .../vmware/src/centreon/vmware/cmdlimitvm.pm | 5 ++--- .../vmware/src/centreon/vmware/cmdmemvm.pm | 5 ++--- .../src/centreon/vmware/cmdsnapshotvm.pm | 5 ++--- .../vmware/src/centreon/vmware/cmdstatusvm.pm | 6 +++--- .../vmware/src/centreon/vmware/cmdswapvm.pm | 5 ++--- .../centreon/vmware/cmdthinprovisioningvm.pm | 5 ++--- .../vmware/src/centreon/vmware/cmdtoolsvm.pm | 5 ++--- 12 files changed, 44 insertions(+), 32 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index f51d1786c..f9d836f56 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,8 @@ +2019-01-06 Quentin Garnier - 3.0.0 + * Enhancement: checking intelligence is moved in centreon-plugins + * Enhancement: autonomous daemon - remove dependency with centreon-plugins-base and perl centreon base library + * Enhancement: update debian doc + 2017-05-31 Quentin Garnier - 2.4.0 * Enhance: Use ZMQ4 library diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index 2633d8f5d..42b3e7e8a 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -30,7 +30,7 @@ sub new { bless $self, $class; $self->{logger} = $options{logger}; - $self->{case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; + $self->{global_case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; return $self; } @@ -75,6 +75,10 @@ sub initArgs { $self->{$_} = $options{arguments}->{$_}; } centreon::vmware::common::init_response(identity => $options{arguments}->{identity}); + + if ($self->{global_case_insensitive} == 0 && defined($self->{case_insensitive})) { + $self->{global_case_insensitive} = 1; + } } sub build_filter { @@ -82,7 +86,7 @@ sub build_filter { my $filters = {}; if (defined($self->{$options{search_option}}) && !defined($self->{$options{is_regexp}})) { - if ($self->{case_insensitive} == 1) { + if ($self->{global_case_insensitive} == 1) { $filters->{name} = qr/^\Q$self->{$options{search_option}}\E$/i; } else { $filters->{name} = qr/^\Q$self->{$options{search_option}}\E$/; @@ -100,4 +104,16 @@ sub build_filter { return $filters; } +sub add_filter { + my ($self, %options) = @_; + + if (defined($self->{$options{search_option}}) && $self->{$options{search_option}} ne '') { + if ($self->{global_case_insensitive} == 1) { + $options{filters}->{$options{label}} = qr/$self->{$options{search_option}}/i; + } else { + $options{filters}->{$options{label}} = qr/$self->{$options{search_option}}/; + } + } +} + 1; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index 806dedd4a..ac7535c3c 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -54,9 +54,8 @@ sub run { } my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 300d0ca60..5c0d93938 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -60,9 +60,8 @@ sub run { my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'datastore', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm index 5da39a60b..c83551c12 100644 --- a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm @@ -53,9 +53,8 @@ sub run { } my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.hardware.device'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index 6904bdb3d..e739df15c 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -49,9 +49,8 @@ sub run { my $self = shift; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); if (defined($self->{check_disk_limit})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index a294868ec..35f5f168d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -54,9 +54,8 @@ sub run { } my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm index b86b4e890..95755e322 100644 --- a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm @@ -49,9 +49,8 @@ sub run { my $self = shift; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{check_consolidation}) == 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm index 47d2d81c9..d46c33252 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm @@ -49,9 +49,9 @@ sub run { my $self = shift; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { push @properties, 'config.annotation'; diff --git a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm index 9ff70ad67..1f6f860cd 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -54,9 +54,8 @@ sub run { } my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index 5b60267b7..c2957a1f0 100644 --- a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -49,9 +49,8 @@ sub run { my $self = shift; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'config.hardware.device', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index 28d122a21..928ff9ef8 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -62,9 +62,8 @@ sub run { my $self = shift; my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); - if (defined($self->{filter_description}) && $self->{filter_description} ne '') { - $filters->{'config.annotation'} = qr/$self->{filter_description}/; - } + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { From bea87605705ccb7ce144f5de8b0fb1d1d8f8f451 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 6 Feb 2019 12:03:08 +0100 Subject: [PATCH 210/447] update changelog --- connectors/vmware/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index f9d836f56..a7ebd7b05 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -2,6 +2,8 @@ * Enhancement: checking intelligence is moved in centreon-plugins * Enhancement: autonomous daemon - remove dependency with centreon-plugins-base and perl centreon base library * Enhancement: update debian doc + * Enhancement: Can filter on guest os virtual machine (option --filter-os in centreon-plugins) + * Enhancement: Can choose case insensitive searching (option --case-insensitive in centreon-plugins) 2017-05-31 Quentin Garnier - 2.4.0 * Enhance: Use ZMQ4 library From 75cc803fabae2b523f20b3c95a3ddf464c3c9cf3 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 6 Feb 2019 14:16:19 +0100 Subject: [PATCH 211/447] enhance health status return --- .../src/centreon/vmware/cmdhealthhost.pm | 54 +++++-------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm index 14d935bff..b47868de1 100644 --- a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm @@ -67,65 +67,39 @@ sub run { # CPU if (defined($cpuStatusInfo)) { - $data->{$entity_value}->{cpu_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; + $data->{$entity_value}->{cpu_info} = []; foreach (@$cpuStatusInfo) { - if ($_->status->key =~ /^red$/i) { - push @{$data->{$entity_value}->{cpu_info}->{summary_red}}, { name => $_->name, summary => $_->status->summary }; - $data->{$entity_value}->{cpu_info}->{red}++; - } elsif ($_->status->key =~ /^yellow$/i) { - push @{$data->{$entity_value}->{cpu_info}->{summary_yellow}}, { name => $_->name, summary => $_->status->summary }; - $data->{$entity_value}->{cpu_info}->{yellow}++; - } else { - $data->{$entity_value}->{cpu_info}->{ok}++; - } + push @{$data->{$entity_value}->{cpu_info}}, { status => $_->status->key, name => $_->name, summary => $_->status->summary }; } } # Memory if (defined($memoryStatusInfo)) { - $data->{$entity_value}->{memory_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; + $data->{$entity_value}->{memory_info} = []; foreach (@$memoryStatusInfo) { - if ($_->status->key =~ /^red$/i) { - push @{$data->{$entity_value}->{memory_info}->{summary_red}}, { name => $_->name, summary => $_->status->summary }; - $data->{$entity_value}->{memory_info}->{red}++; - } elsif ($_->status->key =~ /^yellow$/i) { - push @{$data->{$entity_value}->{memory_info}->{summary_yellow}}, { name => $_->name, summary => $_->status->summary }; - $data->{$entity_value}->{memory_info}->{yellow}++; - } else { - $data->{$entity_value}->{memory_info}->{ok}++; - } + push @{$data->{$entity_value}->{memory_info}}, { status => $_->status->key, name => $_->name, summary => $_->status->summary }; } } # Storage if (defined($self->{storage_status}) && defined($storageStatusInfo)) { - $data->{$entity_value}->{storage_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; + $data->{$entity_value}->{storage_info} = []; foreach (@$storageStatusInfo) { - if ($_->status->key =~ /^red$/i) { - push @{$data->{$entity_value}->{storage_info}->{summary_red}}, { name => $_->name, summary => $_->status->summary }; - $data->{$entity_value}->{storage_info}->{red}++; - } elsif ($_->status->key =~ /^yellow$/i) { - push @{$data->{$entity_value}->{storage_info}->{summary_yellow}}, { name => $_->name, summary => $_->status->summary }; - $data->{$entity_value}->{storage_info}->{yellow}++; - } else { - $data->{$entity_value}->{storage_info}->{ok}++; - } + push @{$data->{$entity_value}->{storage_info}}, { status => $_->status->key, name => $_->name, summary => $_->status->summary }; } } # Sensor if (defined($numericSensorInfo)) { - $data->{$entity_value}->{sensor_info} = { ok => 0, yellow => 0, red => 0, summary_red => [], summary_yellow => [] }; + $data->{$entity_value}->{sensor_info} = []; foreach (@$numericSensorInfo) { - if ($_->healthState->key =~ /^red$/i) { - push @{$data->{$entity_value}->{sensor_info}->{summary_red}}, { type => $_->sensorType, name => $_->name, summary => $_->healthState->summary }; - $data->{$entity_value}->{sensor_info}->{red}++; - } elsif ($_->healthState->key =~ /^yellow$/i) { - push @{$data->{$entity_value}->{sensor_info}->{summary_yellow}}, { type => $_->sensorType, name => $_->name, summary => $_->healthState->summary }; - $data->{$entity_value}->{sensor_info}->{yellow}++; - } else { - $data->{$entity_value}->{sensor_info}->{ok}++; - } + push @{$data->{$entity_value}->{sensor_info}}, { + status => $_->healthState->key, + type => $_->sensorType, name => $_->name, summary => $_->healthState->summary, + current_reading => $_->currentReading, + power10 => $_->unitModifier, + unit => $_->baseUnits + }; } } } From a15a25e99694571996ecdbcb7e06c46a96a83fe3 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 6 Feb 2019 14:39:33 +0100 Subject: [PATCH 212/447] add vmware connector version in response --- connectors/vmware/src/centreon/vmware/common.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index dffaa2ae2..5dacf43c7 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,6 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; + $manager_response->{vmware_connector_version} = '3.0.0'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 653e27103211a631aae315527c80e9ad17bb0c81 Mon Sep 17 00:00:00 2001 From: Matthieu Kermagoret Date: Mon, 11 Feb 2019 09:32:22 +0100 Subject: [PATCH 213/447] add Jenkinsfile script for continuous integration --- connectors/vmware/Jenkinsfile | 35 ++++++++++++++++++++++ connectors/vmware/sonar-project.properties | 3 ++ 2 files changed, 38 insertions(+) create mode 100644 connectors/vmware/Jenkinsfile create mode 100644 connectors/vmware/sonar-project.properties diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile new file mode 100644 index 000000000..2700ef302 --- /dev/null +++ b/connectors/vmware/Jenkinsfile @@ -0,0 +1,35 @@ +stage('Source') { + node { + sh 'setup_centreon_build.sh' + dir('centreon-vmware') { + checkout scm + } + sh './centreon-build/jobs/vmware/vmware-source.sh' + source = readProperties file: 'source.properties' + env.VERSION = "${source.VERSION}" + env.RELEASE = "${source.RELEASE}" + if (env.BRANCH_NAME == 'master') { + withSonarQubeEnv('SonarQube') { + sh './centreon-build/jobs/vmware/vmware-analysis.sh' + } + } + } +} + +try { + stage('Package') { + parallel 'centos7': { + node { + sh 'setup_centreon_build.sh' + sh './centreon-build/jobs/vmware/vmware-package.sh' + } + } + if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { + error('Package stage failure.'); + } + } +} catch(e) { + if (env.BRANCH_NAME == 'master') { + slackSend channel: "#monitoring-metrology", color: "#F30031", message: "*FAILURE*: `CENTREON VMWARE` <${env.BUILD_URL}|build #${env.BUILD_NUMBER}> on branch ${env.BRANCH_NAME}\n*COMMIT*: by ${source.COMMITTER}\n*INFO*: ${e}" + } +} diff --git a/connectors/vmware/sonar-project.properties b/connectors/vmware/sonar-project.properties new file mode 100644 index 000000000..096a60f52 --- /dev/null +++ b/connectors/vmware/sonar-project.properties @@ -0,0 +1,3 @@ +sonar.projectKey=centreon-vmware +sonar.projectName=Centreon VMWare +sonar.sources=. From 3248f2797408acfd2fd50f8b2d111e0fa1a708ed Mon Sep 17 00:00:00 2001 From: Matthieu Kermagoret Date: Mon, 11 Feb 2019 09:56:49 +0100 Subject: [PATCH 214/447] minor update to Jenkinsfile --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 2700ef302..532d4a7e2 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -21,7 +21,7 @@ try { parallel 'centos7': { node { sh 'setup_centreon_build.sh' - sh './centreon-build/jobs/vmware/vmware-package.sh' + sh './centreon-build/jobs/vmware/vmware-package.sh centos7' } } if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { From 42bbebb781ddec84fe13bac63d3734f0cd779098 Mon Sep 17 00:00:00 2001 From: Matthieu Kermagoret Date: Thu, 21 Feb 2019 17:06:12 +0100 Subject: [PATCH 215/447] add CentOS 6 build to Jenkinsfile --- connectors/vmware/Jenkinsfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 532d4a7e2..b2f7a7d91 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -18,7 +18,13 @@ stage('Source') { try { stage('Package') { - parallel 'centos7': { + parallel 'centos6': { + node { + sh 'setup_centreon_build.sh' + sh './centreon-build/jobs/vmware/vmware-package.sh centos6' + } + }, + 'centos7': { node { sh 'setup_centreon_build.sh' sh './centreon-build/jobs/vmware/vmware-package.sh centos7' From 88b36662c3d96dd2eb09f89464b93c6c063f299d Mon Sep 17 00:00:00 2001 From: Louis Sautier Date: Thu, 7 Mar 2019 14:17:31 +0100 Subject: [PATCH 216/447] Fix typo in logs --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index c5ebc78e2..596193406 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -515,7 +515,7 @@ sub bind_ipc { if (zmq_bind($options{socket}, 'ipc://' . $options{ipc_file}) == -1) { $self->{logger}->writeLogError("Cannot bind ipc '$options{ipc_file}': $!"); # try create dir - $self->{logger}->writeLogError("Maybe dirctory not exist. We try to create it!!!"); + $self->{logger}->writeLogError("Maybe directory does not exist. Attempting to create it!!!"); if (!mkdir(dirname($options{ipc_file}))) { zmq_close($options{socket}); exit(1); From 649b949d6c165ce888481efe19e04aba176e0e46 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 4 Apr 2019 18:32:44 +0200 Subject: [PATCH 217/447] add resource-type option for discovery --- .../src/centreon/vmware/cmddiscovery.pm | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 551d7c4b6..b50093b9b 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -1,20 +1,22 @@ -# Copyright 2015 Centreon (http://www.centreon.com/) # -# Centreon is a full-fledged industry-strength solution that meets -# the needs in IT infrastructure and application monitoring for +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for # service performance. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# package centreon::vmware::cmddiscovery; @@ -36,6 +38,13 @@ sub new { sub checkArgs { my ($self, %options) = @_; + + if (defined($options{arguments}->{resource_type}) && $options{arguments}->{resource_type} !~ /^vm$|^esx$/) { + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: resource type must be 'vm' or 'esx'"); + return 1; + } + + $self->{resource_type} = $options{arguments}->{resource_type} if (defined($options{arguments}->{resource_type})); return 0; } @@ -101,7 +110,8 @@ sub run { } } - push @disco_data, \%esx; + push @disco_data, \%esx if ($self->{resource_type} eq 'esx'); + next if ($self->{resource_type} ne 'vm'); @properties = ('config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState'); From b462b5e9fc68a07c0d42ca4935728f3dd0cd83ff Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Mon, 8 Apr 2019 17:28:29 +0200 Subject: [PATCH 218/447] add vm uuid in discovery --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index b50093b9b..b16b353db 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -124,6 +124,7 @@ sub run { $vm{type} = "vm"; $vm{name} = $vm->{'config.name'}; + $vm{uuid} = $vm->{'config.uuid'}; $vm{annotation} = $vm->{'config.annotation'}; $vm{os} = $vm->{'config.guestId'}; $vm{hardware} = $vm->{'config.version'}; From 8fda6409adec2242a7c7fcc92c8dc05331cbcc10 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Wed, 10 Apr 2019 11:36:54 +0200 Subject: [PATCH 219/447] add folder in discovery --- .../src/centreon/vmware/cmddiscovery.pm | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index b16b353db..312f9de96 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -49,6 +49,25 @@ sub checkArgs { return 0; } +sub get_folders { + my ($self, %options) = @_; + + my $folder = $options{folder}; + my $parent = $options{parent}; + my $value = $options{value}; + + $parent .= '/' . $folder->name; + $self->{paths}->{$value} = $parent; + + my $children = $folder->childEntity || return; + for my $child (@{$children}) { + next if $child->type ne 'Folder'; + + $self->get_folders(folder => centreon::vmware::common::get_view($self->{connector}, $child), parent => $parent, + value => $child->value); + } +} + sub run { my $self = shift; @@ -58,13 +77,17 @@ sub run { $disco_stats->{start_time} = time(); my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); - my @properties = ('name', 'hostFolder'); + my @properties = ('name', 'hostFolder', 'vmFolder'); - my $datacenters = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', properties => \@properties, filter => $filters); + my $datacenters = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', + properties => \@properties, filter => $filters); return if (!defined($datacenters)); foreach my $datacenter (@{$datacenters}) { my @properties = ('childType', 'childEntity'); + + $self->get_folders(folder => centreon::vmware::common::get_view($self->{connector}, $datacenter->vmFolder), + parent => '', value => $datacenter->vmFolder->value); my @array; if (defined $datacenter->hostFolder) { @@ -113,7 +136,7 @@ sub run { push @disco_data, \%esx if ($self->{resource_type} eq 'esx'); next if ($self->{resource_type} ne 'vm'); - @properties = ('config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', + @properties = ('parent', 'config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState'); my $vms = centreon::vmware::common::get_views($self->{connector}, \@{$esx->vm}, \@properties); @@ -125,6 +148,7 @@ sub run { $vm{type} = "vm"; $vm{name} = $vm->{'config.name'}; $vm{uuid} = $vm->{'config.uuid'}; + $vm{folder} = $self->{paths}->{$vm->parent->value} if ($vm->parent->type eq 'Folder'); $vm{annotation} = $vm->{'config.annotation'}; $vm{os} = $vm->{'config.guestId'}; $vm{hardware} = $vm->{'config.version'}; From 9329190dc43c105209dd13468828e4aae04c3dff Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Wed, 10 Apr 2019 11:59:49 +0200 Subject: [PATCH 220/447] add filter uuid option for vm --- connectors/vmware/src/centreon/vmware/cmdcpuvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmddatastorevm.pm | 1 + connectors/vmware/src/centreon/vmware/cmddevicevm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdlimitvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdmemvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdstatusvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdswapvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm | 1 + connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm | 1 + 10 files changed, 10 insertions(+) diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index ac7535c3c..cb7ef2d65 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -56,6 +56,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index 5c0d93938..efbf1d32f 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -62,6 +62,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'datastore', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm index c83551c12..0584601f6 100644 --- a/connectors/vmware/src/centreon/vmware/cmddevicevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddevicevm.pm @@ -55,6 +55,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.hardware.device'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm index e739df15c..eabe415eb 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlimitvm.pm @@ -51,6 +51,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.cpuAllocation.limit', 'config.memoryAllocation.limit'); if (defined($self->{check_disk_limit})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm index 35f5f168d..17e8aa7f5 100644 --- a/connectors/vmware/src/centreon/vmware/cmdmemvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdmemvm.pm @@ -56,6 +56,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'summary.config.memorySizeMB', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm index 95755e322..14666f1ac 100644 --- a/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdsnapshotvm.pm @@ -51,6 +51,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('snapshot.rootSnapshotList', 'name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{check_consolidation}) == 1) { diff --git a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm index d46c33252..0e9ecf245 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatusvm.pm @@ -51,6 +51,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm index 1f6f860cd..210204018 100644 --- a/connectors/vmware/src/centreon/vmware/cmdswapvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdswapvm.pm @@ -56,6 +56,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index c2957a1f0..0cbba2baf 100644 --- a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -51,6 +51,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'config.hardware.device', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { diff --git a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm index 928ff9ef8..467928171 100644 --- a/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdtoolsvm.pm @@ -64,6 +64,7 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); my @properties = ('name', 'summary.guest.toolsStatus', 'runtime.connectionState', 'runtime.powerState'); if (defined($self->{display_description})) { From 2c788ad23f8424cf68be21f65b63e5b5945dbace Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 11 Apr 2019 15:57:32 +0200 Subject: [PATCH 221/447] exclude template from vm discovery --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 312f9de96..bd6a0662f 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -143,6 +143,7 @@ sub run { next if (!defined($vms)); foreach my $vm (@{$vms}) { + next if ($vm->{'config.template'} eq 'true'); my %vm; $vm{type} = "vm"; From a79b2fc248d2b9560471f26f81a71ccf25721205 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Fri, 12 Apr 2019 16:34:47 +0200 Subject: [PATCH 222/447] prepare new release --- connectors/vmware/changelog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index a7ebd7b05..c9cc9cfa5 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,8 @@ +2019-04-12 Colin Gagnaire - 3.0.1 + * Enhancement: add resource type filter option for discovery + * Enhancement: add uuid and folder to vm discovery + * Enhancement: add uuid filter in vm modes + 2019-01-06 Quentin Garnier - 3.0.0 * Enhancement: checking intelligence is moved in centreon-plugins * Enhancement: autonomous daemon - remove dependency with centreon-plugins-base and perl centreon base library From 290492972929f06f16b0a0fd05d35c5747b0481e Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Fri, 12 Apr 2019 16:43:06 +0200 Subject: [PATCH 223/447] add version in centreon_vmware.pm --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index c5ebc78e2..66bb15365 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = "3.0.0"; +my $VERSION = "3.0.1"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From 83d363ba5051ed94c57e03722f5ab1a4836d3caf Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Sun, 2 Jun 2019 17:07:28 +0200 Subject: [PATCH 224/447] + Fix #80 --- connectors/vmware/src/centreon/vmware/cmdbase.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index 42b3e7e8a..e734a725d 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -56,7 +56,7 @@ sub class_handle_ALRM { sub handle_ALRM { my $self = shift; - $self->{logger}->writeLogError("Child process autokill!!"); + $self->{logger}->writeLogError('Child process autokill!!'); exit(0); } @@ -94,7 +94,7 @@ sub build_filter { } elsif (!defined($self->{$options{search_option}})) { $filters->{name} = qr/.*/; } else { - if ($self->{case_insensitive} == 1) { + if ($self->{global_case_insensitive} == 1) { $filters->{name} = qr/$self->{$options{search_option}}/i; } else { $filters->{name} = qr/$self->{$options{search_option}}/; From 8fc55ad522613b151a30fed3404d5be92d151135 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Mon, 3 Jun 2019 15:39:41 +0200 Subject: [PATCH 225/447] handle esx without vms --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index bd6a0662f..c2f0c7a28 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -135,6 +135,7 @@ sub run { push @disco_data, \%esx if ($self->{resource_type} eq 'esx'); next if ($self->{resource_type} ne 'vm'); + next if (!$esx->vm); @properties = ('parent', 'config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState'); From 0576bc8a7f6488f05203e5abccee9be66c908ab1 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 6 Jun 2019 15:47:25 +0200 Subject: [PATCH 226/447] handle vm without folder (vapp case) --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index c2f0c7a28..92a3a4ea5 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -150,7 +150,7 @@ sub run { $vm{type} = "vm"; $vm{name} = $vm->{'config.name'}; $vm{uuid} = $vm->{'config.uuid'}; - $vm{folder} = $self->{paths}->{$vm->parent->value} if ($vm->parent->type eq 'Folder'); + $vm{folder} = (defined($vm->parent) && $vm->parent->type eq 'Folder') ? $self->{paths}->{$vm->parent->value} : ''; $vm{annotation} = $vm->{'config.annotation'}; $vm{os} = $vm->{'config.guestId'}; $vm{hardware} = $vm->{'config.version'}; From 566598c04ea3b70e88c381ec569408471e7735bc Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 6 Jun 2019 16:24:54 +0200 Subject: [PATCH 227/447] prepare new release --- connectors/vmware/changelog | 4 ++++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index c9cc9cfa5..6112b17b3 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,7 @@ +2019-06-06 Colin Gagnaire - 3.0.2 + * Fix: ESX with no VMs causes VM discovery to crash + * Fix: VM with no folder causes VM discovery to crash + 2019-04-12 Colin Gagnaire - 3.0.1 * Enhancement: add resource type filter option for discovery * Enhancement: add uuid and folder to vm discovery diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 66bb15365..89631a853 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = "3.0.1"; +my $VERSION = "3.0.2"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From d6ce990c1b336c66e7d544d0fddc5b1dc4200629 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 4 Jul 2019 15:03:30 +0200 Subject: [PATCH 228/447] handle datacenter without cluster, cluster without esx --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 92a3a4ea5..db19108af 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -98,6 +98,7 @@ sub run { next if (!defined($childs)); foreach my $child (@{$childs}) { + next if (!$child->childEntity); my %types = map { $_ => 1 } @{$child->childType}; next if (!defined($types{ComputeResource})); my @properties = ('name', 'host'); @@ -106,6 +107,8 @@ sub run { next if (!defined($clusters)); foreach my $cluster (@{$clusters}) { + next if (!$cluster->host); + my @properties = ('name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState'); From 11d14aaccd607a32e30a673cbccd6990f101c480 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 4 Jul 2019 15:10:11 +0200 Subject: [PATCH 229/447] prepare new release --- connectors/vmware/changelog | 4 ++++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 6112b17b3..0d3d5147c 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,7 @@ +2019-07-04 Colin Gagnaire - 3.0.3 + * Fix: Datacenter with no cluster causes discovery to crash + * Fix: Cluster with no ESX causes discovery to crash + 2019-06-06 Colin Gagnaire - 3.0.2 * Fix: ESX with no VMs causes VM discovery to crash * Fix: VM with no folder causes VM discovery to crash diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 89631a853..33e4874ac 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = "3.0.2"; +my $VERSION = "3.0.3"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( From 4ec0b5677d6518367c817272f16964afd279f91c Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Wed, 14 Aug 2019 10:34:52 +0200 Subject: [PATCH 230/447] handle esx without cluster --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index db19108af..5fc3bdabf 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -100,7 +100,9 @@ sub run { foreach my $child (@{$childs}) { next if (!$child->childEntity); my %types = map { $_ => 1 } @{$child->childType}; - next if (!defined($types{ComputeResource})); + my %entities = map { $_->type => 1 } @{$child->childEntity}; + next if (!defined($types{ComputeResource}) || (!defined($entities{ClusterComputeResource}) && + !defined($entities{ComputeResource}))); my @properties = ('name', 'host'); my $clusters = centreon::vmware::common::get_views($self->{connector}, \@{$child->childEntity}, \@properties); From d5cde61230aac6c78189114ba4f5dc641e6107d8 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 21 Aug 2019 10:33:58 +0200 Subject: [PATCH 231/447] add ipc_file in config file --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 7 ++++--- connectors/vmware/src/centreon/vmware/connector.pm | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 33e4874ac..a856104e2 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -98,11 +98,11 @@ my @load_modules = ( sub new { my $class = shift; - my $self = $class->SUPER::new("centreon_vmware"); + my $self = $class->SUPER::new('centreon_vmware'); bless $self, $class; $self->add_options( - "config-extra=s" => \$self->{opt_extra}, + 'config-extra=s' => \$self->{opt_extra}, ); %{$self->{centreon_vmware_default_config}} = @@ -115,6 +115,7 @@ sub new { dynamic_timeout_kill => 86400, refresh_keeper_session => 15, port => 5700, + ipc_file => '/tmp/centreon_vmware/routing.ipc', case_insensitive => 0, vsphere_server => { #'default' => {'url' => 'https://XXXXXX/sdk', @@ -545,7 +546,7 @@ sub run { zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard zmq_bind($frontend, 'tcp://*:' . $centreon_vmware->{centreon_vmware_config}->{port}); - $centreon_vmware->bind_ipc(socket => $frontend, ipc_file => '/tmp/centreon_vmware/routing.ipc'); + $centreon_vmware->bind_ipc(socket => $frontend, ipc_file => $centreon_vmware->{centreon_vmware_config}->{ipc_file}); foreach (keys %{$centreon_vmware->{centreon_vmware_config}->{vsphere_server}}) { $centreon_vmware->{counter_stats}->{$_} = 0; diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index f559ac9e7..6a0fa9071 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -54,6 +54,7 @@ sub new { $connector->{modules_registry} = $options{modules_registry}; $connector->{logger} = $options{logger}; $connector->{whoaim} = $options{name}; + $connector->{config_ipc_file} = $options{config}->{ipc_file}; $connector->{config_child_timeout} = $options{config}->{timeout}; $connector->{config_stop_child_timeout} = $options{config}->{timeout_kill}; $connector->{config_vsphere_session_heartbeat} = $options{config}->{refresh_keeper_session}; @@ -178,7 +179,7 @@ sub reqclient { $self->{modules_registry}->{$result->{command}}->initArgs(arguments => $result); $self->{modules_registry}->{$result->{command}}->run(); - centreon::vmware::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc:///tmp/centreon_vmware/routing.ipc'); + centreon::vmware::common::response(token => 'RESPSERVER2', endpoint => $backend, reinit => 'ipc://' . $self->{config_ipc_file}); zmq_close($backend); exit(0); } @@ -219,7 +220,7 @@ sub run { $backend = zmq_socket($context, ZMQ_DEALER); zmq_setsockopt($backend, ZMQ_IDENTITY, "server-" . $connector->{whoaim}); zmq_setsockopt($backend, ZMQ_LINGER, 0); # we discard - zmq_connect($backend, 'ipc:///tmp/centreon_vmware/routing.ipc'); + zmq_connect($backend, 'ipc://' . $connector->{config_ipc_file}); centreon::vmware::common::response(token => 'READY', endpoint => $backend, force_response => ''); # Initialize poll set From ef884d2a8d453cc79c4f8833b87d11a184d43d4d Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 26 Aug 2019 14:57:17 +0200 Subject: [PATCH 232/447] WIP: begin vsan --- .../src/centreon/script/centreon_vmware.pm | 25 +++- .../vmware/src/centreon/vmware/cmdbase.pm | 14 ++- .../src/centreon/vmware/cmddatastoreiops.pm | 97 ++++++++++----- .../vmware/src/centreon/vmware/common.pm | 113 ++++++++++++++++-- .../vmware/src/centreon/vmware/connector.pm | 19 +-- 5 files changed, 215 insertions(+), 53 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 703c98347..79b1ee639 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = "3.0.3"; +my $VERSION = "3.1.0"; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( @@ -124,7 +124,8 @@ sub new { #'testvc' => {'url' => 'https://XXXXXX/sdk', # 'username' => 'XXXXX', # 'password' => 'XXXXXX'} - } + }, + vsan_sdk_path => '/usr/share/perl5/VMware', ); $self->{return_child} = {}; @@ -158,6 +159,15 @@ sub init { ##### Load modules $self->load_module(@load_modules); + $self->{vsan_enabled} = 0; + eval { + centreon::vmware::common::load_vsanmgmt_binding_files( + path => $self->{centreon_vmware_config}->{vsan_sdk_path}, + files => ['VIM25VsanmgmtStub.pm', 'VIM25VsanmgmtRuntime.pm'], + ); + $self->{vsan_enabled} = 1; + }; + ##### credstore check ##### if (defined($self->{centreon_vmware_config}->{credstore_use}) && defined($self->{centreon_vmware_config}->{credstore_file}) && $self->{centreon_vmware_config}->{credstore_use} == 1 && -e "$self->{centreon_vmware_config}->{credstore_file}") { @@ -497,10 +507,13 @@ sub create_vsphere_child { return -1; } if ($child_vpshere_pid == 0) { - my $connector = centreon::vmware::connector->new(name => $self->{whoaim}, - modules_registry => $self->{modules_registry}, - config => $self->{centreon_vmware_config}, - logger => $self->{logger}); + my $connector = centreon::vmware::connector->new( + name => $self->{whoaim}, + modules_registry => $self->{modules_registry}, + config => $self->{centreon_vmware_config}, + logger => $self->{logger}, + vsan_enabled => $self->{vsan_enabled}, + ); $connector->run(); exit(0); } diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index e734a725d..9cbf1659e 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -28,7 +28,7 @@ sub new { my ($class, %options) = @_; my $self = {}; bless $self, $class; - + $self->{logger} = $options{logger}; $self->{global_case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; @@ -60,9 +60,19 @@ sub handle_ALRM { exit(0); } +sub is_vsan_enabled { + my ($self, %options) = @_; + + if ($self->{connector}->{vsan_enabled} == 1) { + return 1; + } + + return 0; +} + sub set_connector { my ($self, %options) = @_; - + $self->{connector} = $options{connector}; $self->set_signal_handlers(); alarm(300); diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index c1f3133c1..d11bce3a4 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -54,19 +54,25 @@ sub run { } my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); - my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); + my @properties = ('summary.accessible', 'summary.name', 'summary.type', 'vm', 'info'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - + + my $ds_vsan = {}; + my $data = {}; #my %uuid_list = (); my %disk_name = (); my %datastore_lun = (); my $ds_checked = 0; foreach (@$result) { - $data->{$_->{'summary.name'}} = { name => $_->{'summary.name'}, accessible => $_->{'summary.accessible'} }; + $data->{$_->{'summary.name'}} = { name => $_->{'summary.name'}, accessible => $_->{'summary.accessible'}, type => $_->{'summary.type'} }; next if (centreon::vmware::common::is_accessible(accessible => $_->{'summary.accessible'}) == 0); - + + if ($_->{'summary.type'} eq 'vsan') { + $ds_vsan->{$_->{mo_ref}->{value}} = $_->{'summary.name'}; + $ds_checked = 1; + } if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; # Not need. We are on Datastore level (not LUN level) @@ -82,12 +88,12 @@ sub run { # Zero disk Info #} } - + if ($ds_checked == 0) { centreon::vmware::common::set_response(code => 100, short_message => "No Vmfs datastore(s) checked. Cannot get iops from Nas datastore(s)"); return ; } - + my @vm_array = (); my %added_vm = (); foreach my $entity_view (@$result) { @@ -108,7 +114,7 @@ sub run { @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); - + # Remove disconnected or not running vm my %ref_ids_vm = (); for(my $i = $#{$result2}; $i >= 0; --$i) { @@ -125,21 +131,52 @@ sub run { return ; } - # Vsphere >= 4.1 - my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, - $result2, - [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, - {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{connector}->{perfcounter_speriod}, - sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, - skip_undef_counter => 1, multiples => 1); - - return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - my $interval_sec = $self->{connector}->{perfcounter_speriod}; if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { $interval_sec = $self->{sampling_period}; } + + # VSAN part + if ($self->is_vsan_enabled() && scalar(keys(%$ds_vsan)) > 0) { + my $vsan_performance_mgr = centreon::vmware::common::vsan_create_mo_view( + vsan_vim => $self->{connector}->{vsan_vim}, + type => 'VsanPerformanceManager', + value => 'vsan-performance-manager', + ); + my $cluster_views = centreon::vmware::common::search_entities(command => $self, view_type => 'ComputeResource', properties => ['name', 'datastore'], filter => undef); + my $clusters = {}; + foreach my $cluster_view (@$cluster_views) { + $clusters->{view} = $cluster_view; + foreach (@{$cluster_view->{datastore}}) { + if (defined($ds_vsan->{$_->{value}})) { + $clusters->{ds_vsan} = $_->{value}; + last; + } + } + + centreon::vmware::common::vsan_get_performances( + cluster => $cluster_view, + entityRefId => 'virtual-machine:*', + labels => ['iopsRead', 'iopsWrite'], + interval => $interval_sec, + time_shift => $self->{time_shift} + ); + } + } + + # Vsphere >= 4.1 + my $values = centreon::vmware::common::generic_performance_values_historic( + $self->{connector}, + $result2, + [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, + {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, + skip_undef_counter => 1, multiples => 1 + ); + + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + foreach (keys %$values) { my ($vm_id, $id, $disk_name) = split(/:/); @@ -163,16 +200,20 @@ sub run { $data->{$_}->{'disk.numberWrite.summation'} = $total_write_counter; $data->{$_}->{vm} = {}; - $self->vm_iops_details(label => 'disk.numberRead.summation', - type => 'read', - detail => $datastore_lun{$_}, - ref_vm => \%ref_ids_vm, - data => $data); - $self->vm_iops_details(label => 'disk.numberWrite.summation', - type => 'write', - detail => $datastore_lun{$_}, - ref_vm => \%ref_ids_vm, - data_vm => $data->{$_}->{vm}); + $self->vm_iops_details( + label => 'disk.numberRead.summation', + type => 'read', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm, + data => $data + ); + $self->vm_iops_details( + label => 'disk.numberWrite.summation', + type => 'write', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm, + data_vm => $data->{$_}->{vm} + ); } centreon::vmware::common::set_response(data => $data); diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 5dacf43c7..1309737a8 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -103,21 +103,26 @@ sub vmware_error { } sub connect_vsphere { - my ($logger, $whoaim, $timeout_vsphere, $session1, $service_url, $username, $password) = @_; - $logger->writeLogInfo("'$whoaim' Vsphere connection in progress"); + my (%options) = @_; + + $options{logger}->writeLogInfo("'$options{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($options{connect_timeout}); + $options{connector}->{session1} = Vim->new(service_url => $options{url}); + $options{connector}->{session1}->login( + user_name => $options{username}, + password => $options{password} + ); + + get_vsan_vim(%options) if ($options{vsan_enabled} == 1); + alarm(0); }; if ($@) { - $logger->writeLogError("'$whoaim' No response from VirtualCenter server") if($@ =~ /TIMEOUT/); - $logger->writeLogError("'$whoaim' You need to upgrade HTTP::Message!") if($@ =~ /HTTP::Message/); - $logger->writeLogError("'$whoaim' Login to VirtualCenter server failed: $@"); + $options{logger}->writeLogError("'$options{whoaim}' No response from VirtualCenter server") if($@ =~ /TIMEOUT/); + $options{logger}->writeLogError("'$options{whoaim}' You need to upgrade HTTP::Message!") if($@ =~ /HTTP::Message/); + $options{logger}->writeLogError("'$options{whoaim}' Login to VirtualCenter server failed: $@"); return 1; } # eval { @@ -626,4 +631,92 @@ sub stats_info { set_response(data => $data); } +# +# Vsan +# + +sub load_vsanmgmt_binding_files { + my (%options) = @_; + + my @stub = (); + local $/; + for (@{$options{files}}) { + open(STUB, $options{path} . '/' . $_) or die $!; + push @stub, split /\n####+?\n/, ; + close STUB or die $!; + } + for (@stub) { + my ($package) = /\bpackage\s+(\w+)/; + $VIMRuntime::stub_class{$package} = $_ if (defined($package)); + } + eval $VIMRuntime::stub_class{'VimService'}; +} + +sub get_vsan_vim { + my (%options) = @_; + + require URI::URL; + my $session_id = $options{connector}->{session1}->get_session_id(); + my $url = URI::URL->new($options{connector}->{session1}->get_service_url()); + my $api_type = $options{connector}->{session1}->get_service_content()->about->apiType; + + my $service_url_path = "sdk/vimService"; + my $path = "vsanHealth"; + if ($api_type eq "HostAgent") { + $service_url_path = "sdk"; + $path = "vsan"; + } + + $options{connector}->{vsan_vim} = Vim->new( + service_url => + 'https://' . $url->host . '/' . $service_url_path, + server => $url->host, + protocol => "https", + path => $path, + port => '443' + ); + + $options{connector}->{vsan_vim}->{vim_service} = VimService->new($options{connector}->{vsan_vim}->{service_url}); + $options{connector}->{vsan_vim}->{vim_service}->load_session_id($session_id); + $options{connector}->{vsan_vim}->unset_logout_on_disconnect; +} + +sub vsan_create_mo_view { + my (%options) = @_; + + my $moref = ManagedObjectReference->new( + type => $options{type}, + value => $options{value}, + ); + my $view_type = $moref->type; + my $mo_view = $view_type->new($moref, $options{vsan_vim}); + return $mo_view; +} + +sub vsan_get_performances { + my (%options) = @_; + + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; + my $tstamp = time(); + my (@t) = gmtime($tstamp - $options{interval} - $time_shift); + 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]); + my $querySpec = VsanPerfQuerySpec->new( + entityRefId => $options{entityRefId}, # for example: 'virtual-machine:*' + labels => $options{labels}, # for example: ['iopsRead, iopsWrite'] + startTime = $startTime, + endTime = $endTime, + ); + my $values = $options{vsan_performance_mgr}->VsanPerfQueryPerf( + querySpecs => [$querySpec], + cluster => $options{cluster}, + ); + + use Data::Dumper; + print Data::Dumper::Dumper($values); +} + 1; diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index 6a0fa9071..e546ba4c6 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -54,6 +54,7 @@ sub new { $connector->{modules_registry} = $options{modules_registry}; $connector->{logger} = $options{logger}; $connector->{whoaim} = $options{name}; + $connector->{vsan_enabled} = $options{vsan_enabled}; $connector->{config_ipc_file} = $options{config}->{ipc_file}; $connector->{config_child_timeout} = $options{config}->{timeout}; $connector->{config_stop_child_timeout} = $options{config}->{timeout_kill}; @@ -272,13 +273,17 @@ sub run { } if ($connector->{vsphere_connected} == 0) { - if (!centreon::vmware::common::connect_vsphere($connector->{logger}, - $connector->{whoaim}, - $connector->{config_vsphere_connect_timeout}, - \$connector->{session1}, - $connector->{config_vsphere_url}, - $connector->{config_vsphere_user}, - $connector->{config_vsphere_pass})) { + if (!centreon::vmware::common::connect_vsphere( + logger => $connector->{logger}, + whoaim => $connector->{whoaim}, + connect_timeout => $connector->{config_vsphere_connect_timeout}, + connector => $connector, + url => $connector->{config_vsphere_url}, + username => $connector->{config_vsphere_user}, + password => $connector->{config_vsphere_pass}, + vsan_enabled => $connector->{vsan_enabled}, + ) + ) { $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Vsphere connection ok"); $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Create perf counters cache in progress"); if (!centreon::vmware::common::cache_perf_counters($connector)) { From 8e7aa0b987448c0de5db19426d56f7293f82a781 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 26 Aug 2019 15:11:28 +0200 Subject: [PATCH 233/447] WIP vsan --- .../src/centreon/vmware/cmddatastoreiops.pm | 9 ++++++--- .../vmware/src/centreon/vmware/common.pm | 20 +++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index d11bce3a4..06ca1670f 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -146,21 +146,24 @@ sub run { my $cluster_views = centreon::vmware::common::search_entities(command => $self, view_type => 'ComputeResource', properties => ['name', 'datastore'], filter => undef); my $clusters = {}; foreach my $cluster_view (@$cluster_views) { - $clusters->{view} = $cluster_view; + $clusters->{$cluster_view->{name}} = {}; foreach (@{$cluster_view->{datastore}}) { if (defined($ds_vsan->{$_->{value}})) { - $clusters->{ds_vsan} = $_->{value}; + $clusters->{$cluster_view->{name}}->{ds_vsan} = $_->{value}; last; } } - centreon::vmware::common::vsan_get_performances( + next if (!defined($clusters->{$cluster_view->{name}}->{ds_vsan})); + my $result = centreon::vmware::common::vsan_get_performances( + vsan_performance_mgr => $vsan_performance_mgr, cluster => $cluster_view, entityRefId => 'virtual-machine:*', labels => ['iopsRead', 'iopsWrite'], interval => $interval_sec, time_shift => $self->{time_shift} ); + use Data::Dumper; print Data::Dumper::Dumper($result); } } diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 1309737a8..e8ecbfe5b 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -707,16 +707,28 @@ sub vsan_get_performances { my $querySpec = VsanPerfQuerySpec->new( entityRefId => $options{entityRefId}, # for example: 'virtual-machine:*' labels => $options{labels}, # for example: ['iopsRead, iopsWrite'] - startTime = $startTime, - endTime = $endTime, + startTime => $startTime, + endTime => $endTime, ); my $values = $options{vsan_performance_mgr}->VsanPerfQueryPerf( querySpecs => [$querySpec], cluster => $options{cluster}, ); - use Data::Dumper; - print Data::Dumper::Dumper($values); + my $result = {}; + foreach (@$values) { + $result->{$_->{entityRefId}} = {}; + foreach my $perf (@{$_->{value}}) { + my ($counter, $i) = (0, 0); + foreach my $val (split /,/, $perf->{values}) { + $counter += $val; + $i++; + } + $result->{$_->{entityRefId}}->{$perf->{metricId}->{label}} = $counter / $i; + } + } + + return $result; } 1; From 5b009c10bd98cd4ad9adbb292b0d5a83ecb52759 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 26 Aug 2019 16:01:47 +0200 Subject: [PATCH 234/447] WIP vsan --- .../src/centreon/vmware/cmddatastoreiops.pm | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 06ca1670f..9e718c693 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -111,19 +111,21 @@ sub run { return ; } - @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); + @properties = ('name', 'config.uuid', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); # Remove disconnected or not running vm - my %ref_ids_vm = (); + my ($moref_vm, $uuid_vm) = ({}, {}); for(my $i = $#{$result2}; $i >= 0; --$i) { if (!centreon::vmware::common::is_connected(state => ${$result2}[$i]->{'runtime.connectionState'}->val) || !centreon::vmware::common::is_running(power => ${$result2}[$i]->{'runtime.powerState'}->val)) { splice @$result2, $i, 1; next; } - $ref_ids_vm{${$result2}[$i]->{mo_ref}->{value}} = ${$result2}[$i]->{name}; + + $uuid_vm->{$result2->[$i]->{config.uuid}} = $result2->[$i]->{mo_ref}->{value}; + $moref_vm->{$result2->[$i]->{mo_ref}->{value}} = $result2->[$i]->{name}; } if (scalar(@{$result2}) == 0) { @@ -163,7 +165,21 @@ sub run { interval => $interval_sec, time_shift => $self->{time_shift} ); - use Data::Dumper; print Data::Dumper::Dumper($result); + + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} } = { + 'disk.numberRead.summation' => 0, + 'disk.numberWrite.summation' => 0, + }; + # we recreate format: vm-{movalue}_disk.numberWrite.summation + foreach (keys %$result) { + next if (! /virtual-machine:(.*)/); + next if (!defined($uuid_vm->{$1})); + my $moref = $uuid_vm->{$1}; + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'vm-' . $moref . '_disk.numberRead.summation'} = $result->{$_}->{iopsRead}; + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'vm-' . $moref . '_disk.numberWrite.summation'} = $result->{$_}->{iopsWrite}; + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'disk.numberRead.summation'} += $result->{$_}->{iopsRead}; + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'disk.numberWrite.summation'} += $result->{$_}->{iopsWrite}; + } } } @@ -171,8 +187,10 @@ sub run { my $values = centreon::vmware::common::generic_performance_values_historic( $self->{connector}, $result2, - [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, - {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], + [ + { label => 'disk.numberRead.summation', instances => ['*'] }, + { label => 'disk.numberWrite.summation', instances => ['*'] } + ], $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, skip_undef_counter => 1, multiples => 1 @@ -207,14 +225,14 @@ sub run { label => 'disk.numberRead.summation', type => 'read', detail => $datastore_lun{$_}, - ref_vm => \%ref_ids_vm, + ref_vm => $moref_vm, data => $data ); $self->vm_iops_details( label => 'disk.numberWrite.summation', type => 'write', detail => $datastore_lun{$_}, - ref_vm => \%ref_ids_vm, + ref_vm => $moref_vm, data_vm => $data->{$_}->{vm} ); } From 6ece2886579d1cddd72644e9f67af198983c7d22 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 26 Aug 2019 16:36:03 +0200 Subject: [PATCH 235/447] WIP vsan: add datastoreiops --- .../src/centreon/vmware/cmddatastoreiops.pm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm index 9e718c693..965255d2c 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreiops.pm @@ -111,20 +111,20 @@ sub run { return ; } - @properties = ('name', 'config.uuid', 'runtime.connectionState', 'runtime.powerState'); + @properties = ('name', 'summary.config.instanceUuid', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::vmware::common::get_views($self->{connector}, \@vm_array, \@properties); return if (!defined($result2)); # Remove disconnected or not running vm my ($moref_vm, $uuid_vm) = ({}, {}); for(my $i = $#{$result2}; $i >= 0; --$i) { - if (!centreon::vmware::common::is_connected(state => ${$result2}[$i]->{'runtime.connectionState'}->val) || - !centreon::vmware::common::is_running(power => ${$result2}[$i]->{'runtime.powerState'}->val)) { + if (!centreon::vmware::common::is_connected(state => $result2->[$i]->{'runtime.connectionState'}->val) || + !centreon::vmware::common::is_running(power => $result2->[$i]->{'runtime.powerState'}->val)) { splice @$result2, $i, 1; next; } - $uuid_vm->{$result2->[$i]->{config.uuid}} = $result2->[$i]->{mo_ref}->{value}; + $uuid_vm->{$result2->[$i]->{'summary.config.instanceUuid'}} = $result2->[$i]->{mo_ref}->{value}; $moref_vm->{$result2->[$i]->{mo_ref}->{value}} = $result2->[$i]->{name}; } @@ -151,7 +151,7 @@ sub run { $clusters->{$cluster_view->{name}} = {}; foreach (@{$cluster_view->{datastore}}) { if (defined($ds_vsan->{$_->{value}})) { - $clusters->{$cluster_view->{name}}->{ds_vsan} = $_->{value}; + $clusters->{$cluster_view->{name}}->{ds_vsan} = $ds_vsan->{$_->{value}}; last; } } @@ -175,8 +175,8 @@ sub run { next if (! /virtual-machine:(.*)/); next if (!defined($uuid_vm->{$1})); my $moref = $uuid_vm->{$1}; - $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'vm-' . $moref . '_disk.numberRead.summation'} = $result->{$_}->{iopsRead}; - $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'vm-' . $moref . '_disk.numberWrite.summation'} = $result->{$_}->{iopsWrite}; + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{$moref . '_disk.numberRead.summation'} = $result->{$_}->{iopsRead}; + $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{$moref . '_disk.numberWrite.summation'} = $result->{$_}->{iopsWrite}; $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'disk.numberRead.summation'} += $result->{$_}->{iopsRead}; $datastore_lun{ $clusters->{$cluster_view->{name}}->{ds_vsan} }->{'disk.numberWrite.summation'} += $result->{$_}->{iopsWrite}; } @@ -226,7 +226,7 @@ sub run { type => 'read', detail => $datastore_lun{$_}, ref_vm => $moref_vm, - data => $data + data_vm => $data->{$_}->{vm} ); $self->vm_iops_details( label => 'disk.numberWrite.summation', From 985e5a317082790ac65947044bde2ec8f972b9c3 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 26 Aug 2019 17:07:10 +0200 Subject: [PATCH 236/447] Fix #81 --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 79b1ee639..a3400792e 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -114,6 +114,7 @@ sub new { timeout_kill => 30, dynamic_timeout_kill => 86400, refresh_keeper_session => 15, + bind => '*', port => 5700, ipc_file => '/tmp/centreon_vmware/routing.ipc', case_insensitive => 0, @@ -558,7 +559,7 @@ sub run { } zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard - zmq_bind($frontend, 'tcp://*:' . $centreon_vmware->{centreon_vmware_config}->{port}); + zmq_bind($frontend, 'tcp://' . $centreon_vmware->{centreon_vmware_config}->{bind} . ':' . $centreon_vmware->{centreon_vmware_config}->{port}); $centreon_vmware->bind_ipc(socket => $frontend, ipc_file => $centreon_vmware->{centreon_vmware_config}->{ipc_file}); foreach (keys %{$centreon_vmware->{centreon_vmware_config}->{vsphere_server}}) { From f018c577df1cc23364c750dc786ca39cfb63a447 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 27 Aug 2019 10:37:48 +0200 Subject: [PATCH 237/447] add cluster status command --- .../src/centreon/script/centreon_vmware.pm | 1 + .../src/centreon/vmware/cmdstatuscluster.pm | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index a3400792e..5ada8a14b 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -85,6 +85,7 @@ my @load_modules = ( 'centreon::vmware::cmdnethost', 'centreon::vmware::cmdservicehost', 'centreon::vmware::cmdsnapshotvm', + 'centreon::vmware::cmdstatuscluster', 'centreon::vmware::cmdstatushost', 'centreon::vmware::cmdstatusvm', 'centreon::vmware::cmdswaphost', diff --git a/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm b/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm new file mode 100644 index 000000000..a21891244 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm @@ -0,0 +1,87 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdstatuscluster; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'statuscluster'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{cluster_name}) && $options{arguments}->{cluster_name} eq '') { + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: cluster name cannot be null"); + return 1; + } + + return 0; +} + +sub run { + my $self = shift; + + my $vsan_cluster_health; + my $filters = $self->build_filter(label => 'name', search_option => 'cluster_name', is_regexp => 'filter'); + my @properties = ('name', 'summary.overallStatus'); + if ($self->is_vsan_enabled()) { + $vsan_cluster_health = = centreon::vmware::common::vsan_create_mo_view( + vsan_vim => $self->{connector}->{vsan_vim}, + type => 'VsanVcClusterHealthSystem', + value => 'vsan-cluster-health-system', + ); + push @properties, 'configurationEx'; + } + my $views = centreon::vmware::common::search_entities(command => $self, view_type => ' ComputeResource', properties => \@properties, filter => $filters); + return if (!defined($views)); + + my $data = {}; + foreach my $view (@$views) { + my $entity_value = $view->{mo_ref}->{value}; + $data->{$entity_value} = { + name => $view->{name}, + overall_status => $view->{'summary.overallStatus'}->val; + }; + + if (defined($view->{configurationEx}->{vsanConfigInfo}) && $view->{configurationEx}->{vsanConfigInfo}->enabled == 1) { + my $summary = $vsan_cluster_health->VsanQueryVcClusterHealthSummary( + cluster => $view, + includeObjUuids => 'false', + fetchFromCache => 'false', + fields => ['clusterStatus'], + ); + $data->{$entity_value}->{vsan_cluster_status} = $summary->clusterStatus; + } + } + + centreon::vmware::common::set_response(data => $data); +} + +1; From 2c8694fdfd92c54289f56f786c46ea69ed61852b Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 27 Aug 2019 11:01:32 +0200 Subject: [PATCH 238/447] fix cluster status --- connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm b/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm index a21891244..e8414b3dc 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm @@ -52,14 +52,14 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'cluster_name', is_regexp => 'filter'); my @properties = ('name', 'summary.overallStatus'); if ($self->is_vsan_enabled()) { - $vsan_cluster_health = = centreon::vmware::common::vsan_create_mo_view( + $vsan_cluster_health = centreon::vmware::common::vsan_create_mo_view( vsan_vim => $self->{connector}->{vsan_vim}, type => 'VsanVcClusterHealthSystem', value => 'vsan-cluster-health-system', ); push @properties, 'configurationEx'; } - my $views = centreon::vmware::common::search_entities(command => $self, view_type => ' ComputeResource', properties => \@properties, filter => $filters); + my $views = centreon::vmware::common::search_entities(command => $self, view_type => 'ComputeResource', properties => \@properties, filter => $filters); return if (!defined($views)); my $data = {}; @@ -67,7 +67,7 @@ sub run { my $entity_value = $view->{mo_ref}->{value}; $data->{$entity_value} = { name => $view->{name}, - overall_status => $view->{'summary.overallStatus'}->val; + overall_status => $view->{'summary.overallStatus'}->val }; if (defined($view->{configurationEx}->{vsanConfigInfo}) && $view->{configurationEx}->{vsanConfigInfo}->enabled == 1) { @@ -77,7 +77,7 @@ sub run { fetchFromCache => 'false', fields => ['clusterStatus'], ); - $data->{$entity_value}->{vsan_cluster_status} = $summary->clusterStatus; + $data->{$entity_value}->{vsan_cluster_status} = $summary->clusterStatus->status; } } From 29713684ef6dabdb7043c4671d41cb43d03222fb Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 27 Aug 2019 11:13:45 +0200 Subject: [PATCH 239/447] wip: vsan cluster usage --- .../src/centreon/script/centreon_vmware.pm | 1 + .../centreon/vmware/cmdvsanclusterusage.pm | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 5ada8a14b..9c2bc46b3 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -95,6 +95,7 @@ my @load_modules = ( 'centreon::vmware::cmdtoolsvm', 'centreon::vmware::cmduptimehost', 'centreon::vmware::cmdvmoperationcluster', + 'centreon::vmware::cmdvsancluserusage', ); sub new { diff --git a/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm b/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm new file mode 100644 index 000000000..a5eb4917d --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm @@ -0,0 +1,105 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdvsanclusterusage; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'vsanclusterusage'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{cluster_name}) && $options{arguments}->{cluster_name} eq '') { + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: cluster name cannot be null"); + return 1; + } + + return 0; +} + +sub run { + my $self = shift; + + if (!$self->is_vsan_enabled()) { + centreon::vmware::common::set_response(code => 100, short_message => 'Vsan is not enabled in vmware connector'); + return ; + } + + my $filters = $self->build_filter(label => 'name', search_option => 'cluster_name', is_regexp => 'filter'); + my @properties = ('name', 'configurationEx'); + my $views = centreon::vmware::common::search_entities(command => $self, view_type => 'ComputeResource', properties => \@properties, filter => $filters); + return if (!defined($views)); + + my $vsan_performance_mgr = centreon::vmware::common::vsan_create_mo_view( + vsan_vim => $self->{connector}->{vsan_vim}, + type => 'VsanPerformanceManager', + value => 'vsan-performance-manager', + ); + + my $interval_sec = $self->{connector}->{perfcounter_speriod}; + if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { + $interval_sec = $self->{sampling_period}; + } + + my $data = {}; + foreach my $view (@$views) { + if (!defined($view->{configurationEx}->{vsanConfigInfo}) || $view->{configurationEx}->{vsanConfigInfo}->enabled != 1); + + my $entity_value = $view->{mo_ref}->{value}; + $data->{$entity_value} = { + name => $view->{name}, + }; + + my $result = centreon::vmware::common::vsan_get_performances( + vsan_performance_mgr => $vsan_performance_mgr, + cluster => $view, + entityRefId => 'cluster-domcompmgr:*', + labels => [ + 'iopsRead', + 'iopsWrite', + 'congestion', # number + 'latencyAvgRead', # time_ms + 'latencyAvgWrite', # time_ms + 'oio', # outstanding IO (number), + 'throughputRead', # rate_bytes + 'throughputWrite', # rate_bytes + ], + interval => $interval_sec, + time_shift => $self->{time_shift} + ); + + use Data::Dumper; print Data::Dumper::Dumper($result); + } + + centreon::vmware::common::set_response(data => $data); +} + +1; From 862267d9f447b6d1b5e0c77af711fe2e19efa291 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 27 Aug 2019 11:40:58 +0200 Subject: [PATCH 240/447] wip: vsan cluster usage --- .../src/centreon/script/centreon_vmware.pm | 2 +- .../src/centreon/vmware/cmdvsanclusterusage.pm | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 9c2bc46b3..7712b0371 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -95,7 +95,7 @@ my @load_modules = ( 'centreon::vmware::cmdtoolsvm', 'centreon::vmware::cmduptimehost', 'centreon::vmware::cmdvmoperationcluster', - 'centreon::vmware::cmdvsancluserusage', + 'centreon::vmware::cmdvsanclusterusage', ); sub new { diff --git a/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm b/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm index a5eb4917d..c51fcfc67 100644 --- a/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm @@ -71,13 +71,10 @@ sub run { my $data = {}; foreach my $view (@$views) { - if (!defined($view->{configurationEx}->{vsanConfigInfo}) || $view->{configurationEx}->{vsanConfigInfo}->enabled != 1); + next if (!defined($view->{configurationEx}->{vsanConfigInfo}) || $view->{configurationEx}->{vsanConfigInfo}->enabled != 1); my $entity_value = $view->{mo_ref}->{value}; - $data->{$entity_value} = { - name => $view->{name}, - }; - + my $uuid = $view->{configurationEx}->{vsanConfigInfo}->{defaultConfig}->{uuid}; my $result = centreon::vmware::common::vsan_get_performances( vsan_performance_mgr => $vsan_performance_mgr, cluster => $view, @@ -95,10 +92,13 @@ sub run { interval => $interval_sec, time_shift => $self->{time_shift} ); - - use Data::Dumper; print Data::Dumper::Dumper($result); + $data->{$entity_value} = { + name => $view->{name}, + cluster_domcompmgr => %{$result->{'cluster-domcompmgr:' . $uuid}}, + }; } - + + use Data::Dumper; print Data::Dumper::Dumper($data); centreon::vmware::common::set_response(data => $data); } From ac779c1d895d189205628c54c52f07266f2b48b0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 27 Aug 2019 11:42:48 +0200 Subject: [PATCH 241/447] add vsan cluster usage cmd --- connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm b/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm index c51fcfc67..ff298ab44 100644 --- a/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmdvsanclusterusage.pm @@ -94,11 +94,12 @@ sub run { ); $data->{$entity_value} = { name => $view->{name}, - cluster_domcompmgr => %{$result->{'cluster-domcompmgr:' . $uuid}}, + cluster_domcompmgr => { + %{$result->{'cluster-domcompmgr:' . $uuid}} + }, }; } - use Data::Dumper; print Data::Dumper::Dumper($data); centreon::vmware::common::set_response(data => $data); } From 335601da8bde1091ea3a49cf178ae2c4ee4fa5a0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 27 Aug 2019 13:52:54 +0200 Subject: [PATCH 242/447] prepare new release --- connectors/vmware/changelog | 5 +++++ connectors/vmware/src/centreon/vmware/common.pm | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 0d3d5147c..e98889819 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,8 @@ +2019-08-27 Quentin Garnier - 3.1.0 + * Enhancement: add 'status-cluster' and 'vsan-cluster-usage' + * Fix: Can listen only on localhost (issue #81) + * Fix: Can configure ipc_file location + 2019-07-04 Colin Gagnaire - 3.0.3 * Fix: Datacenter with no cluster causes discovery to crash * Fix: Cluster with no ESX causes discovery to crash diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index e8ecbfe5b..7f358c770 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.0.0'; + $manager_response->{vmware_connector_version} = '3.1.0'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 4191b6f35004661bad77dde7e5aee7b4d9119459 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 18 Oct 2019 16:37:36 +0200 Subject: [PATCH 243/447] fix undefined error in thinprovisioningvm --- connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm index 0cbba2baf..38c8a942a 100644 --- a/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdthinprovisioningvm.pm @@ -77,7 +77,8 @@ sub run { foreach (@{$entity_view->{'config.hardware.device'}}) { if ($_->isa('VirtualDisk')) { - push @{$data->{$entity_value}->{disks}}, { thin_provisioned => $_->backing->thinProvisioned, name => $_->backing->fileName }; + next if (!defined($_->{backing}->{thinProvisioned})); + push @{$data->{$entity_value}->{disks}}, { thin_provisioned => $_->{backing}->{thinProvisioned}, name => $_->{backing}->{fileName} }; } } } From 9659b393c71b3cbd4690332160d6fed66fd71542 Mon Sep 17 00:00:00 2001 From: Louis Sautier Date: Thu, 30 Jan 2020 11:25:18 +0100 Subject: [PATCH 244/447] Change default vsan_sdk_path to match perl-VMware-vSphere's install path The RPM provided by Centreon installs its files in /usr/local/share/perl5/VMware. --- connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 7712b0371..a5340c0e6 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -128,7 +128,7 @@ sub new { # 'username' => 'XXXXX', # 'password' => 'XXXXXX'} }, - vsan_sdk_path => '/usr/share/perl5/VMware', + vsan_sdk_path => '/usr/local/share/perl5/VMware', ); $self->{return_child} = {}; From 12e545e235ccf88fb2010da6b8ee867dfefd4b4f Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 4 Feb 2020 15:30:24 +0100 Subject: [PATCH 245/447] indent + manage no vm running --- .../src/centreon/vmware/cmddatastorevm.pm | 7 +- .../vmware/src/centreon/vmware/common.pm | 274 +++++++++++------- 2 files changed, 170 insertions(+), 111 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm index efbf1d32f..ddd6fb575 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorevm.pm @@ -105,7 +105,12 @@ sub run { } } } - + + if (scalar(@ds_array) == 0) { + centreon::vmware::common::set_response(code => 200, short_message => "no virtual machines running or no datastore found"); + return ; + } + @properties = ('info'); my $result2 = centreon::vmware::common::get_views($self->{connector}, \@ds_array, \@properties); return if (!defined($result2)); diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 7f358c770..691b4fdaa 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -33,7 +33,7 @@ my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; sub set_response { my (%options) = @_; - + $manager_response->{code} = $options{code} if (defined($options{code})); $manager_response->{short_message} = $options{short_message} if (defined($options{short_message})); $manager_response->{extra_message} = $options{extra_message} if (defined($options{extra_message})); @@ -43,7 +43,7 @@ sub set_response { sub init_response { my (%options) = @_; - + $manager_response->{code} = 0; $manager_response->{vmware_connector_version} = '3.1.0'; $manager_response->{short_message} = 'OK'; @@ -70,7 +70,7 @@ sub response { $response_str = '{ "code": -1, "short_message": "Cannot encode result" }'; } } - + if (defined($options{reinit})) { my $context = zmq_init(); $options{endpoint} = zmq_socket($context, ZMQ_DEALER); @@ -104,7 +104,7 @@ sub vmware_error { sub connect_vsphere { my (%options) = @_; - + $options{logger}->writeLogInfo("'$options{whoaim}' Vsphere connection in progress"); eval { $SIG{ALRM} = sub { die('TIMEOUT'); }; @@ -114,9 +114,9 @@ sub connect_vsphere { user_name => $options{username}, password => $options{password} ); - + get_vsan_vim(%options) if ($options{vsan_enabled} == 1); - + alarm(0); }; if ($@) { @@ -138,7 +138,7 @@ sub connect_vsphere { sub heartbeat { my (%options) = @_; my $stime; - + eval { $stime = $options{connector}->{session1}->get_service_instance()->CurrentTime(); $options{connector}->{keeper_session_time} = time(); @@ -157,7 +157,7 @@ sub heartbeat { $options{connector}->{last_time_check} = time(); } } - + $options{connector}->{logger}->writeLogInfo("'" . $options{connector}->{whoaim} . "' Get current time = " . Data::Dumper::Dumper($stime)); } @@ -206,12 +206,13 @@ sub get_view { sub search_in_datastore { my (%options) = @_; my $result; - - my $files = FileQueryFlags->new(fileSize => 1, - fileType => 1, - modification => 1, - fileOwner => 1 - ); + + my $files = FileQueryFlags->new( + fileSize => 1, + fileType => 1, + modification => 1, + fileOwner => 1 + ); my $hostdb_search_spec = HostDatastoreBrowserSearchSpec->new( details => $files, searchCaseInsensitive => $options{searchCaseInsensitive}, @@ -219,8 +220,10 @@ sub search_in_datastore { query => $options{query} ); eval { - $result = $options{browse_ds}->SearchDatastoreSubFolders(datastorePath => $options{ds_name}, - searchSpec => $hostdb_search_spec); + $result = $options{browse_ds}->SearchDatastoreSubFolders( + datastorePath => $options{ds_name}, + searchSpec => $hostdb_search_spec + ); }; if ($@) { return (undef, $@) if (defined($options{return}) && $options{return} == 1); @@ -233,20 +236,26 @@ sub search_in_datastore { sub get_perf_metric_ids { my (%options) = @_; my $filtered_list = []; - + foreach (@{$options{metrics}}) { if (defined($options{connector}->{perfcounter_cache}->{$_->{label}})) { if ($options{interval} != 20 && $options{connector}->{perfcounter_cache}->{$_->{label}}{level} > $options{connector}->{sampling_periods}->{$options{interval}}->{level}) { - set_response(code => -1, - short_message => sprintf("Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", - $_->{label}, $options{interval}, - $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, - $options{connector}->{sampling_periods}->{$options{interval}}->{level})); + set_response( + code => -1, + short_message => sprintf( + "Cannot get counter '%s' for the sampling period '%s' (counter level: %s, sampling level: %s)", + $_->{label}, $options{interval}, + $options{connector}->{perfcounter_cache}->{$_->{label}}{level}, + $options{connector}->{sampling_periods}->{$options{interval}}->{level} + ) + ); return undef; } foreach my $instance (@{$_->{instances}}) { - my $metric = PerfMetricId->new(counterId => $options{connector}->{perfcounter_cache}->{$_->{label}}{key}, - instance => $instance); + my $metric = PerfMetricId->new( + counterId => $options{connector}->{perfcounter_cache}->{$_->{label}}{key}, + instance => $instance + ); push @$filtered_list, $metric; } } else { @@ -260,85 +269,102 @@ sub get_perf_metric_ids { sub performance_builder_specific { my (%options) = @_; - + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; my @perf_query_spec; foreach my $entry (@{$options{metrics}}) { - my $perf_metric_ids = get_perf_metric_ids(connector => $options{connector}, - metrics => $entry->{metrics}, - interval => $options{interval}); + my $perf_metric_ids = get_perf_metric_ids( + connector => $options{connector}, + metrics => $entry->{metrics}, + interval => $options{interval} + ); return undef if (!defined($perf_metric_ids)); - + my $tstamp = time(); my (@t) = gmtime($tstamp - $options{interval} - $time_shift); - my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + 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]); + my $endTime = sprintf( + "%04d-%02d-%02dT%02d:%02d:%02dZ", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0] + ); if ($options{interval} == 20) { - push @perf_query_spec, PerfQuerySpec->new(entity => $entry->{entity}, - metricId => $perf_metric_ids, - format => 'normal', - intervalId => 20, - startTime => $startTime, - endTime => $endTime - ); - #maxSample => 1); + push @perf_query_spec, PerfQuerySpec->new( + entity => $entry->{entity}, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => 20, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); } else { - push @perf_query_spec, PerfQuerySpec->new(entity => $entry->{entity}, - metricId => $perf_metric_ids, - format => 'normal', - intervalId => $options{interval}, - startTime => $startTime, - endTime => $endTime - ); - #maxSample => 1); + push @perf_query_spec, PerfQuerySpec->new( + entity => $entry->{entity}, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => $options{interval}, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); } } - + return $options{connector}->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); } sub performance_builder_global { my (%options) = @_; - + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; my @perf_query_spec; - my $perf_metric_ids = get_perf_metric_ids(connector => $options{connector}, - metrics => $options{metrics}, - interval => $options{interval}); + my $perf_metric_ids = get_perf_metric_ids( + connector => $options{connector}, + metrics => $options{metrics}, + interval => $options{interval} + ); return undef if (!defined($perf_metric_ids)); - + my $tstamp = time(); my (@t) = gmtime($tstamp - $options{interval} - $time_shift); - my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + 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]); - + my $endTime = sprintf( + "%04d-%02d-%02dT%02d:%02d:%02dZ", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0] + ); + foreach (@{$options{views}}) { if ($options{interval} == 20) { - push @perf_query_spec, PerfQuerySpec->new(entity => $_, - metricId => $perf_metric_ids, - format => 'normal', - intervalId => 20, - startTime => $startTime, - endTime => $endTime); - #maxSample => 1); + push @perf_query_spec, PerfQuerySpec->new( + entity => $_, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => 20, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); } else { - push @perf_query_spec, PerfQuerySpec->new(entity => $_, - metricId => $perf_metric_ids, - format => 'normal', - intervalId => $options{interval}, - startTime => $startTime, - endTime => $endTime - ); - #maxSample => 1); + push @perf_query_spec, PerfQuerySpec->new( + entity => $_, + metricId => $perf_metric_ids, + format => 'normal', + intervalId => $options{interval}, + startTime => $startTime, + endTime => $endTime + ); + #maxSample => 1); } } - + return $options{connector}->{perfmanager_view}->QueryPerf(querySpec => \@perf_query_spec); } @@ -346,7 +372,7 @@ sub generic_performance_values_historic { my ($obj_vmware, $views, $perfs, $interval, %options) = @_; my $counter = 0; my %results; - + # overload the default sampling choosen if (defined($options{sampling_period}) && $options{sampling_period} ne '') { $interval = $options{sampling_period}; @@ -362,16 +388,22 @@ sub generic_performance_values_historic { } eval { my $perfdata; - + if (defined($views)) { - $perfdata = performance_builder_global(connector => $obj_vmware, - views => $views, - metrics => $perfs, - interval => $interval, time_shift => $options{time_shift}); + $perfdata = performance_builder_global( + connector => $obj_vmware, + views => $views, + metrics => $perfs, + interval => $interval, + time_shift => $options{time_shift} + ); } else { - $perfdata = performance_builder_specific(connector => $obj_vmware, - metrics => $perfs, - interval => $interval, time_shift => $options{time_shift}); + $perfdata = performance_builder_specific( + connector => $obj_vmware, + metrics => $perfs, + interval => $interval, + time_shift => $options{time_shift} + ); } return undef if (!defined($perfdata)); @@ -388,7 +420,7 @@ sub generic_performance_values_historic { set_response(code => -1, short_message => 'Cannot get value for counters. Maybe there is time sync problem (check the esxd server and the target also)'); return undef; } - + my $aggregated_counter_value = 0; foreach my $counter_value (@{$_->value}) { $aggregated_counter_value += $counter_value; @@ -396,7 +428,7 @@ sub generic_performance_values_historic { if (scalar(@{$_->value}) > 1) { $aggregated_counter_value /= scalar(@{$_->value}); } - + if (defined($options{multiples}) && $options{multiples} == 1) { if (defined($options{multiples_result_by_entity}) && $options{multiples_result_by_entity} == 1) { $results{$val->{entity}->{value}} = {} if (!defined($results{$val->{entity}->{value}})); @@ -412,8 +444,14 @@ sub generic_performance_values_historic { }; if ($@) { if ($@ =~ /querySpec.interval.*InvalidArgumentFault/msi) { - set_response(code => -1, short_message => sprintf("Interval '%s' is surely not supported for the managed entity (caller: %s)", - $interval, join('--', caller))); + set_response( + code => -1, + short_message => sprintf( + "Interval '%s' is surely not supported for the managed entity (caller: %s)", + $interval, + join('--', caller) + ) + ); } else { $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); } @@ -459,20 +497,26 @@ sub search_entities { my (%options) = @_; my $properties = ['name']; my $begin_views = []; - + foreach my $scope (['scope_datacenter', 'Datacenter'], ['scope_cluster', 'ClusterComputeResource'], ['scope_host', 'HostSystem']) { if (defined($options{command}->{$$scope[0]}) && $options{command}->{$$scope[0]} ne '') { my $filters = { name => qr/$options{command}->{$$scope[0]}/ }; if (scalar(@$begin_views) > 0) { my $temp_views = []; while ((my $view = shift @$begin_views)) { - my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $$scope[1], properties => $properties, filter => $filters, - begin_entity => $view, output_message => 0); + my ($status, $views) = find_entity_views( + connector => $options{command}->{connector}, + view_type => $$scope[1], + properties => $properties, + filter => $filters, + begin_entity => $view, + output_message => 0 + ); next if ($status == 0); return undef if ($status == -1); push @$temp_views, @$views; } - + if (scalar(@$temp_views) == 0) { set_response(code => 1, short_message => "Cannot find '$$scope[1]' object"); return undef; @@ -486,12 +530,18 @@ sub search_entities { } } } - + if (scalar(@$begin_views) > 0) { my $results = []; foreach my $view (@$begin_views) { - my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, - begin_entity => $view, output_message => 0); + my ($status, $views) = find_entity_views( + connector => $options{command}->{connector}, + view_type => $options{view_type}, + properties => $options{properties}, + filter => $options{filter}, + begin_entity => $view, + output_message => 0 + ); next if ($status == 0); return undef if ($status == -1); push @$results, @$views; @@ -559,19 +609,19 @@ sub performance_errors { sub get_interval_min { my (%options) = @_; - + my $interval = $options{speriod}; my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; if (defined($options{sampling_period}) && $options{sampling_period} ne '') { $interval = $options{sampling_period}; } - + return int(($interval + $time_shift) / 60); } sub is_accessible { my (%options) = @_; - + if ($options{accessible} !~ /^true|1$/) { return 0; } @@ -580,7 +630,7 @@ sub is_accessible { sub is_connected { my (%options) = @_; - + if ($options{state} !~ /^connected$/i) { return 0; } @@ -589,7 +639,7 @@ sub is_connected { sub is_running { my (%options) = @_; - + if ($options{power} !~ /^poweredOn$/i) { return 0; } @@ -598,7 +648,7 @@ sub is_running { sub is_maintenance { my (%options) = @_; - + if ($options{maintenance} =~ /^true|1$/) { return 0; } @@ -607,14 +657,14 @@ sub is_maintenance { sub substitute_name { my (%options) = @_; - + $options{value} =~ s/%2f/\//g; return $options{value}; } sub strip_cr { my (%options) = @_; - + $options{value} =~ s/^\s+.*\s+$//mg; $options{value} =~ s/\r//mg; $options{value} =~ s/\n/ -- /mg; @@ -659,7 +709,7 @@ sub get_vsan_vim { my $session_id = $options{connector}->{session1}->get_session_id(); my $url = URI::URL->new($options{connector}->{session1}->get_service_url()); my $api_type = $options{connector}->{session1}->get_service_content()->about->apiType; - + my $service_url_path = "sdk/vimService"; my $path = "vsanHealth"; if ($api_type eq "HostAgent") { @@ -695,15 +745,19 @@ sub vsan_create_mo_view { sub vsan_get_performances { my (%options) = @_; - + my $time_shift = defined($options{time_shift}) ? $options{time_shift} : 0; my $tstamp = time(); my (@t) = gmtime($tstamp - $options{interval} - $time_shift); - my $startTime = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", - (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0]); + 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]); + my $endTime = sprintf( + "%04d-%02d-%02dT%02d:%02d:%02dZ", + (1900+$t[5]),(1+$t[4]),$t[3],$t[2],$t[1],$t[0] + ); my $querySpec = VsanPerfQuerySpec->new( entityRefId => $options{entityRefId}, # for example: 'virtual-machine:*' labels => $options{labels}, # for example: ['iopsRead, iopsWrite'] From 57a1c6c577c7ef9dec0d3e23886819b6b3cd9e30 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 5 Feb 2020 11:46:39 +0100 Subject: [PATCH 246/447] enhance discovery folders management --- .../src/centreon/vmware/cmddiscovery.pm | 179 ++++++++++-------- 1 file changed, 96 insertions(+), 83 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 5fc3bdabf..fc6e90d10 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -59,12 +59,15 @@ sub get_folders { $parent .= '/' . $folder->name; $self->{paths}->{$value} = $parent; - my $children = $folder->childEntity || return; - for my $child (@{$children}) { - next if $child->type ne 'Folder'; + my $children = $folder->childEntity || return; + for my $child (@{$children}) { + next if ($child->type ne 'Folder'); - $self->get_folders(folder => centreon::vmware::common::get_view($self->{connector}, $child), parent => $parent, - value => $child->value); + $self->get_folders( + folder => centreon::vmware::common::get_view($self->{connector}, $child), + parent => $parent, + value => $child->value + ); } } @@ -79,96 +82,106 @@ sub run { my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); my @properties = ('name', 'hostFolder', 'vmFolder'); - my $datacenters = centreon::vmware::common::search_entities(command => $self, view_type => 'Datacenter', - properties => \@properties, filter => $filters); + my $datacenters = centreon::vmware::common::search_entities( + command => $self, + view_type => 'Datacenter', + properties => \@properties, + filter => $filters + ); return if (!defined($datacenters)); foreach my $datacenter (@{$datacenters}) { - my @properties = ('childType', 'childEntity'); - - $self->get_folders(folder => centreon::vmware::common::get_view($self->{connector}, $datacenter->vmFolder), - parent => '', value => $datacenter->vmFolder->value); + my @properties = ('name', 'host'); - my @array; - if (defined $datacenter->hostFolder) { - push @array, $datacenter->hostFolder; - } + $self->get_folders( + folder => centreon::vmware::common::get_view($self->{connector}, $datacenter->vmFolder), + parent => '', + value => $datacenter->vmFolder->value + ); - my $childs = centreon::vmware::common::get_views($self->{connector}, \@array, \@properties); - next if (!defined($childs)); + my ($status, childs); + my $clusters = []; + ($status, $childs) = centreon::vmware::common::find_entity_views( + connector => $self->{connector}, + view_type => 'ClusterComputeResource', + properties => \@properties, + filter => $filters, + begin_entity => $datacenter, + output_message => 0 + ); + push $clusters, @$childs if (defined($childs)); + ($status, $childs) = centreon::vmware::common::find_entity_views( + connector => $self->{connector}, + view_type => 'ComputeResource', + properties => \@properties, + filter => $filters, + begin_entity => $datacenter, + output_message => 0 + ); + push $clusters, @$childs if (defined($childs)); - foreach my $child (@{$childs}) { - next if (!$child->childEntity); - my %types = map { $_ => 1 } @{$child->childType}; - my %entities = map { $_->type => 1 } @{$child->childEntity}; - next if (!defined($types{ComputeResource}) || (!defined($entities{ClusterComputeResource}) && - !defined($entities{ComputeResource}))); - my @properties = ('name', 'host'); - - my $clusters = centreon::vmware::common::get_views($self->{connector}, \@{$child->childEntity}, \@properties); - next if (!defined($clusters)); + foreach my $cluster (@$clusters) { + next if (!$cluster->{'host'}); - foreach my $cluster (@{$clusters}) { - next if (!$cluster->host); + my @properties = ('name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', + 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', + 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState'); - my @properties = ('name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', - 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', - 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState'); - - my $esxs = centreon::vmware::common::get_views($self->{connector}, \@{$cluster->host}, \@properties); - next if (!defined($esxs)); + my $esxs = centreon::vmware::common::get_views($self->{connector}, \@{$cluster->host}, \@properties); + next if (!defined($esxs)); - foreach my $esx (@{$esxs}) { - my %esx; - - $esx{type} = "esx"; - $esx{name} = $esx->name; - $esx{os} = $esx->{'config.product.productLineId'} . ' ' . $esx->{'config.product.version'}; - $esx{hardware} = $esx->{'hardware.systemInfo.vendor'} . ' ' . $esx->{'hardware.systemInfo.model'}; - $esx{power_state} = $esx->{'runtime.powerState'}->val; - $esx{connection_state} = $esx->{'runtime.connectionState'}->val; - $esx{maintenance} = $esx->{'runtime.inMaintenanceMode'}; - $esx{datacenter} = $datacenter->name; - $esx{cluster} = $cluster->name; + foreach my $esx (@$esxs) { + my %esx; - foreach my $nic (@{$esx->{'config.virtualNicManagerInfo.netConfig'}}) { - my %lookup = map { $_->{'key'} => $_->{'spec'}->{'ip'}->{'ipAddress'} } @{$nic->{'candidateVnic'}}; - foreach my $vnic (@{$nic->{'selectedVnic'}}) { - push @{$esx{'ip_' . $nic->{'nicType'}}}, $lookup{$vnic}; - } + $esx{type} = "esx"; + $esx{name} = $esx->name; + $esx{os} = $esx->{'config.product.productLineId'} . ' ' . $esx->{'config.product.version'}; + $esx{hardware} = $esx->{'hardware.systemInfo.vendor'} . ' ' . $esx->{'hardware.systemInfo.model'}; + $esx{power_state} = $esx->{'runtime.powerState'}->val; + $esx{connection_state} = $esx->{'runtime.connectionState'}->val; + $esx{maintenance} = $esx->{'runtime.inMaintenanceMode'}; + $esx{datacenter} = $datacenter->name; + $esx{cluster} = $cluster->name; + + foreach my $nic (@{$esx->{'config.virtualNicManagerInfo.netConfig'}}) { + my %lookup = map { $_->{'key'} => $_->{'spec'}->{'ip'}->{'ipAddress'} } @{$nic->{'candidateVnic'}}; + foreach my $vnic (@{$nic->{'selectedVnic'}}) { + push @{$esx{'ip_' . $nic->{'nicType'}}}, $lookup{$vnic}; } - - push @disco_data, \%esx if ($self->{resource_type} eq 'esx'); - next if ($self->{resource_type} ne 'vm'); - next if (!$esx->vm); + } - @properties = ('parent', 'config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', - 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState'); + push @disco_data, \%esx if (defined($self->{resource_type}) && $self->{resource_type} eq 'esx'); + next if (!defined($self->{resource_type}) || $self->{resource_type} ne 'vm'); + next if (!$esx->vm); - my $vms = centreon::vmware::common::get_views($self->{connector}, \@{$esx->vm}, \@properties); - next if (!defined($vms)); - - foreach my $vm (@{$vms}) { - next if ($vm->{'config.template'} eq 'true'); - my %vm; - - $vm{type} = "vm"; - $vm{name} = $vm->{'config.name'}; - $vm{uuid} = $vm->{'config.uuid'}; - $vm{folder} = (defined($vm->parent) && $vm->parent->type eq 'Folder') ? $self->{paths}->{$vm->parent->value} : ''; - $vm{annotation} = $vm->{'config.annotation'}; - $vm{os} = $vm->{'config.guestId'}; - $vm{hardware} = $vm->{'config.version'}; - $vm{guest_name} = $vm->{'guest.hostName'}; - $vm{guest_ip} = $vm->{'guest.ipAddress'}; - $vm{guest_state} = $vm->{'guest.guestState'}; - $vm{power_state} = $vm->{'runtime.powerState'}->val; - $vm{datacenter} = $datacenter->name; - $vm{cluster} = $cluster->name; - $vm{esx} = $esx->name; - - push @disco_data, \%vm; - } + @properties = ( + 'parent', 'config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', + 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState' + ); + + my $vms = centreon::vmware::common::get_views($self->{connector}, \@{$esx->vm}, \@properties); + next if (!defined($vms)); + + foreach my $vm (@{$vms}) { + next if ($vm->{'config.template'} eq 'true'); + my %vm; + + $vm{type} = 'vm'; + $vm{name} = $vm->{'config.name'}; + $vm{uuid} = $vm->{'config.uuid'}; + $vm{folder} = (defined($vm->parent) && $vm->parent->type eq 'Folder') ? $self->{paths}->{$vm->parent->value} : ''; + $vm{annotation} = $vm->{'config.annotation'}; + $vm{os} = $vm->{'config.guestId'}; + $vm{hardware} = $vm->{'config.version'}; + $vm{guest_name} = $vm->{'guest.hostName'}; + $vm{guest_ip} = $vm->{'guest.ipAddress'}; + $vm{guest_state} = $vm->{'guest.guestState'}; + $vm{power_state} = $vm->{'runtime.powerState'}->val; + $vm{datacenter} = $datacenter->name; + $vm{cluster} = $cluster->name; + $vm{esx} = $esx->name; + + push @disco_data, \%vm; } } } @@ -178,7 +191,7 @@ sub run { $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; $disco_stats->{discovered_items} = @disco_data; $disco_stats->{results} = \@disco_data; - + centreon::vmware::common::set_response(data => $disco_stats); } From 5ff8a33b110123e7ee4fae03f0138124f81e1de0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 5 Feb 2020 16:25:59 +0100 Subject: [PATCH 247/447] fix duplicate discovery entries --- .../vmware/src/centreon/vmware/cmddiscovery.pm | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index fc6e90d10..62a012695 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -99,26 +99,15 @@ sub run { value => $datacenter->vmFolder->value ); - my ($status, childs); - my $clusters = []; - ($status, $childs) = centreon::vmware::common::find_entity_views( + my ($status, $clusters) = centreon::vmware::common::find_entity_views( connector => $self->{connector}, - view_type => 'ClusterComputeResource', + view_type => 'ComputeResource', # ClusterComputeResource extends ComputeResource. so no need to check it properties => \@properties, filter => $filters, begin_entity => $datacenter, output_message => 0 ); - push $clusters, @$childs if (defined($childs)); - ($status, $childs) = centreon::vmware::common::find_entity_views( - connector => $self->{connector}, - view_type => 'ComputeResource', - properties => \@properties, - filter => $filters, - begin_entity => $datacenter, - output_message => 0 - ); - push $clusters, @$childs if (defined($childs)); + next if ($status <= 0); foreach my $cluster (@$clusters) { next if (!$cluster->{'host'}); From 5e8186963c588fd95e92ee4dd7990e6388f34e8a Mon Sep 17 00:00:00 2001 From: schapron Date: Thu, 13 Feb 2020 09:28:51 +0100 Subject: [PATCH 248/447] sec(doc): add SECURITY.md --- connectors/vmware/SECURITY.md | 96 +++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 connectors/vmware/SECURITY.md diff --git a/connectors/vmware/SECURITY.md b/connectors/vmware/SECURITY.md new file mode 100644 index 000000000..1aed97a92 --- /dev/null +++ b/connectors/vmware/SECURITY.md @@ -0,0 +1,96 @@ +# Security Policy + +Centreon takes the security of our software products seriously. + +If you believe you have found a security vulnerability, please report it to us as described below. + +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +Send an email to security@centreon.com. If possible, encrypt your message with our PGP key below. + +You should receive a response within 48 hours. If for some reason you do not, please follow up via email to ensure we received your original message. + +To help us better understand the nature and scope of the possible issue, please describe as much as you can: + +* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue + +## PGP information + +### Public key + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +oWAyTvK/VwbB77CTz1yTUSE= +=3kAj +-----END PGP PUBLIC KEY BLOCK----- +``` + +| Tag | Value | +| -- | -- | +| ID | BEAF6EBF631106F9 | +| Type | RSA | +| Size | 4096 | +| Created | 2020-02-11 | +| Expires | 2021-02-10 | +| Cipher |AES-256| +| Fingerprint | C377 E9D5 2D5C 137D 3DD5 73B5 BEA F6EBF 6311 06F9 | + +## Bug bounty + +We don't have a bug bounty program but this is something we are thinking about. From ba6bcf15335f1751f4d787e5dfbd3b46151c1c98 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 20 Feb 2020 13:42:17 +0100 Subject: [PATCH 249/447] prepare version 3.1.1 --- connectors/vmware/changelog | 5 +++++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index e98889819..a5193a249 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,8 @@ +2020-02-20 Quentin Garnier - 3.1.1 + * Fix: discovery folders management + * Fix: no virtual machines running for 'datastore-vm' + * Fix: undefined error for 'thinprovisioning-vm' + 2019-08-27 Quentin Garnier - 3.1.0 * Enhancement: add 'status-cluster' and 'vsan-cluster-usage' * Fix: Can listen only on localhost (issue #81) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index a5340c0e6..c4f03df22 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = "3.1.0"; +my $VERSION = '3.1.1'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 691b4fdaa..4ec05e57a 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.1.0'; + $manager_response->{vmware_connector_version} = '3.1.1'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 6c75fd1868b1618c0c1b36527e5d5dd7382f4dfd Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 6 Apr 2020 13:55:41 +0200 Subject: [PATCH 250/447] add drs and das config enable 'cluster-status' --- connectors/vmware/changelog | 3 +++ .../src/centreon/script/centreon_vmware.pm | 2 +- .../src/centreon/vmware/cmdstatuscluster.pm | 16 +++++++++------- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index a5193a249..1a20bfd38 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2020-04-06 Quentin Garnier - 3.1.2 + * Enhancement: add drs and das config enable 'cluster-status' + 2020-02-20 Quentin Garnier - 3.1.1 * Fix: discovery folders management * Fix: no virtual machines running for 'datastore-vm' diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index c4f03df22..64164764c 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.1.1'; +my $VERSION = '3.1.2'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm b/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm index e8414b3dc..843785130 100644 --- a/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdstatuscluster.pm @@ -38,7 +38,7 @@ sub checkArgs { my ($self, %options) = @_; if (defined($options{arguments}->{cluster_name}) && $options{arguments}->{cluster_name} eq '') { - centreon::vmware::common::set_response(code => 100, short_message => "Argument error: cluster name cannot be null"); + centreon::vmware::common::set_response(code => 100, short_message => 'Argument error: cluster name cannot be null'); return 1; } @@ -50,7 +50,7 @@ sub run { my $vsan_cluster_health; my $filters = $self->build_filter(label => 'name', search_option => 'cluster_name', is_regexp => 'filter'); - my @properties = ('name', 'summary.overallStatus'); + my @properties = ('name', 'summary.overallStatus', 'configuration'); if ($self->is_vsan_enabled()) { $vsan_cluster_health = centreon::vmware::common::vsan_create_mo_view( vsan_vim => $self->{connector}->{vsan_vim}, @@ -59,15 +59,17 @@ sub run { ); push @properties, 'configurationEx'; } - my $views = centreon::vmware::common::search_entities(command => $self, view_type => 'ComputeResource', properties => \@properties, filter => $filters); + my $views = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); return if (!defined($views)); - + my $data = {}; foreach my $view (@$views) { my $entity_value = $view->{mo_ref}->{value}; $data->{$entity_value} = { name => $view->{name}, - overall_status => $view->{'summary.overallStatus'}->val + overall_status => $view->{'summary.overallStatus'}->val, + ha_enabled => (defined($view->{configuration}->{dasConfig}->{enabled}) && $view->{configuration}->{dasConfig}->{enabled} =~ /^1|true/i) ? 'true' : 'false', + drs_enabled => (defined($view->{configuration}->{drsConfig}->{enabled}) && $view->{configuration}->{drsConfig}->{enabled} =~ /^1|true/i) ? 'true' : 'false' }; if (defined($view->{configurationEx}->{vsanConfigInfo}) && $view->{configurationEx}->{vsanConfigInfo}->enabled == 1) { @@ -75,12 +77,12 @@ sub run { cluster => $view, includeObjUuids => 'false', fetchFromCache => 'false', - fields => ['clusterStatus'], + fields => ['clusterStatus'] ); $data->{$entity_value}->{vsan_cluster_status} = $summary->clusterStatus->status; } } - + centreon::vmware::common::set_response(data => $data); } diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 4ec05e57a..984b8cfeb 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.1.1'; + $manager_response->{vmware_connector_version} = '3.1.2'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 485a4518ffd843547d05b1da0f61bfd2a89fe64c Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 6 Apr 2020 16:22:27 +0200 Subject: [PATCH 251/447] fix error in logs from net-host --- connectors/vmware/changelog | 1 + .../vmware/src/centreon/vmware/cmdnethost.pm | 65 ++++++++++--------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 1a20bfd38..0bde1569f 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,5 +1,6 @@ 2020-04-06 Quentin Garnier - 3.1.2 * Enhancement: add drs and das config enable 'cluster-status' + * Fix: remove errors in logs 'net-host' 2020-02-20 Quentin Garnier - 3.1.1 * Fix: discovery folders management diff --git a/connectors/vmware/src/centreon/vmware/cmdnethost.pm b/connectors/vmware/src/centreon/vmware/cmdnethost.pm index 222742b89..0312ba7fb 100644 --- a/connectors/vmware/src/centreon/vmware/cmdnethost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdnethost.pm @@ -28,20 +28,20 @@ sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(%options); bless $self, $class; - + $self->{commandName} = 'nethost'; - + return $self; } sub checkArgs { my ($self, %options) = @_; - if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { - centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq '') { + centreon::vmware::common::set_response(code => 100, short_message => 'Argument error: esx hostname cannot be null'); return 1; } - + return 0; } @@ -61,7 +61,7 @@ sub run { } my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); - + my $data = {}; my $pnic_def_up = {}; my $query_perfs = []; @@ -73,7 +73,7 @@ sub run { $pnic_def_up->{$entity_value} = {}; my $instances = []; - + # Get Name from vswitch if (defined($entity_view->{'config.network.vswitch'})) { foreach (@{$entity_view->{'config.network.vswitch'}}) { @@ -85,15 +85,16 @@ sub run { # Get Name from proxySwitch if (defined($entity_view->{'config.network.proxySwitch'})) { foreach (@{$entity_view->{'config.network.proxySwitch'}}) { - $data->{$entity_value}->{proxyswitch}->{$_->{name}} = { pnic => [] }; + my $name = defined($_->{name}) ? $_->{name} : $_->{key}; + $data->{$entity_value}->{proxyswitch}->{$name} = { pnic => [] }; next if (!defined($_->{pnic})); - push @{$data->{$entity_value}->{proxyswitch}->{$_->{name}}->{pnic}}, @{$_->{pnic}}; + push @{$data->{$entity_value}->{proxyswitch}->{$name}->{pnic}}, @{$_->{pnic}}; } } foreach (@{$entity_view->{'config.network.pnic'}}) { $data->{$entity_value}->{pnic}->{$_->device} = { speed => undef, status => 'down', key => $_->{key} }; - + $number_nic++; if (defined($_->linkSpeed)) { $data->{$entity_value}->{pnic}->{$_->device}->{speed} = $_->linkSpeed->speedMb; @@ -105,29 +106,31 @@ sub run { } push @$query_perfs, { - entity => $entity_view, - metrics => [ - {label => 'net.received.average', instances => $instances}, - {label => 'net.transmitted.average', instances => $instances}, - {label => 'net.droppedRx.summation', instances => $instances}, - {label => 'net.droppedTx.summation', instances => $instances}, - {label => 'net.packetsRx.summation', instances => $instances}, - {label => 'net.packetsTx.summation', instances => $instances} - ] - }; + entity => $entity_view, + metrics => [ + {label => 'net.received.average', instances => $instances}, + {label => 'net.transmitted.average', instances => $instances}, + {label => 'net.droppedRx.summation', instances => $instances}, + {label => 'net.droppedTx.summation', instances => $instances}, + {label => 'net.packetsRx.summation', instances => $instances}, + {label => 'net.packetsTx.summation', instances => $instances} + ] + }; } - + # Nothing to retrieve. problem before already. return if (scalar(@$query_perfs) == 0); - - my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, - undef, - $query_perfs, - $self->{connector}->{perfcounter_speriod}, - sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, - skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); + + my $values = centreon::vmware::common::generic_performance_values_historic( + $self->{connector}, + undef, + $query_perfs, + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1 + ); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - + foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; @@ -139,7 +142,7 @@ sub run { my $packets_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.packetsTx.summation'}->{key} . ":" . $_})); my $dropped_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedRx.summation'}->{key} . ":" . $_})); my $dropped_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'net.droppedTx.summation'}->{key} . ":" . $_})); - + $data->{$entity_value}->{pnic}->{$_}->{'net.received.average'} = $traffic_in; $data->{$entity_value}->{pnic}->{$_}->{'net.transmitted.average'} = $traffic_out; $data->{$entity_value}->{pnic}->{$_}->{'net.packetsRx.summation'} = $packets_in; @@ -148,7 +151,7 @@ sub run { $data->{$entity_value}->{pnic}->{$_}->{'net.droppedTx.summation'} = $dropped_out; } } - + centreon::vmware::common::set_response(data => $data); } From b5d871a74526ae109264cca76d4ef1d5b3d8424e Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 30 Apr 2020 16:10:31 +0200 Subject: [PATCH 252/447] enh(discovery): remove carriage return from vm annotation --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 62a012695..e18321e6d 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -160,6 +160,7 @@ sub run { $vm{uuid} = $vm->{'config.uuid'}; $vm{folder} = (defined($vm->parent) && $vm->parent->type eq 'Folder') ? $self->{paths}->{$vm->parent->value} : ''; $vm{annotation} = $vm->{'config.annotation'}; + $vm{annotation} =~ s/\n/ /g if (defined($vm{annotation})); $vm{os} = $vm->{'config.guestId'}; $vm{hardware} = $vm->{'config.version'}; $vm{guest_name} = $vm->{'guest.hostName'}; From ca19ff1222ddfe115d694ce66e3fce273c7f0dde Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Tue, 2 Jun 2020 11:35:01 +0200 Subject: [PATCH 253/447] feat(rn): prepare 3.1.2 release --- connectors/vmware/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 0bde1569f..3afebf429 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,5 +1,6 @@ 2020-04-06 Quentin Garnier - 3.1.2 * Enhancement: add drs and das config enable 'cluster-status' + * Enhancement: remove carriage return from vm annotation in discovery * Fix: remove errors in logs 'net-host' 2020-02-20 Quentin Garnier - 3.1.1 From d89c969daa61040dd82895d4cd9f811706fba4cb Mon Sep 17 00:00:00 2001 From: Matthieu Kermagoret Date: Tue, 9 Jun 2020 16:01:15 +0200 Subject: [PATCH 254/447] feat(build): add CentOS 8 to build pipeline. --- connectors/vmware/Jenkinsfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index b2f7a7d91..ffe9203e5 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -29,6 +29,12 @@ try { sh 'setup_centreon_build.sh' sh './centreon-build/jobs/vmware/vmware-package.sh centos7' } + }, + 'centos8': { + node { + sh 'setup_centreon_build.sh' + sh './centreon-build/jobs/vmware/vmware-package.sh centos8' + } } if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { error('Package stage failure.'); From 948c3814be589015cbfcdebfdacfe3563e534ff1 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 31 Jul 2020 11:37:13 +0200 Subject: [PATCH 255/447] add netvm check --- .../src/centreon/script/centreon_vmware.pm | 1 + .../vmware/src/centreon/vmware/cmdnetvm.pm | 113 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 connectors/vmware/src/centreon/vmware/cmdnetvm.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 64164764c..e47e0413d 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -83,6 +83,7 @@ my @load_modules = ( 'centreon::vmware::cmdmaintenancehost', 'centreon::vmware::cmdmemvm', 'centreon::vmware::cmdnethost', + 'centreon::vmware::cmdnetvm', 'centreon::vmware::cmdservicehost', 'centreon::vmware::cmdsnapshotvm', 'centreon::vmware::cmdstatuscluster', diff --git a/connectors/vmware/src/centreon/vmware/cmdnetvm.pm b/connectors/vmware/src/centreon/vmware/cmdnetvm.pm new file mode 100644 index 000000000..ab7442c6b --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdnetvm.pm @@ -0,0 +1,113 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdnetvm; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'netvm'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{vm_hostname}) && $options{arguments}->{vm_hostname} eq "") { + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: vm hostname cannot be null"); + return 1; + } + + return 0; +} + +sub run { + my $self = shift; + + if (!($self->{connector}->{perfcounter_speriod} > 0)) { + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); + return ; + } + + my $filters = $self->build_filter(label => 'name', search_option => 'vm_hostname', is_regexp => 'filter'); + $self->add_filter(filters => $filters, label => 'config.annotation', search_option => 'filter_description'); + $self->add_filter(filters => $filters, label => 'config.guestFullName', search_option => 'filter_os'); + $self->add_filter(filters => $filters, label => 'config.uuid', search_option => 'filter_uuid'); + + my @properties = ('name', 'runtime.connectionState', 'runtime.powerState', 'config.hardware.device'); + if (defined($self->{display_description})) { + push @properties, 'config.annotation'; + } + + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'VirtualMachine', properties => \@properties, filter => $filters); + return if (!defined($result)); + + my $values = centreon::vmware::common::generic_performance_values_historic( + $self->{connector}, + $result, + [ + { label => 'net.received.average', instances => ['*'] }, + { label => 'net.transmitted.average', instances => ['*'] } + ], + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1 + ); + + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + + my $data = {}; + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + connection_state => $entity_view->{'runtime.connectionState'}->val, + power_state => $entity_view->{'runtime.powerState'}->val, + 'config.annotation' => defined($entity_view->{'config.annotation'}) ? $entity_view->{'config.annotation'} : undef, + interfaces => {} + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_running(power => $entity_view->{'runtime.powerState'}->val) == 0); + + foreach (@{$entity_view->{'config.hardware.device'}}) { + next if (! $_->isa('VirtualEthernetCard')); + + # KBps + my $traffic_in = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{ $self->{connector}->{perfcounter_cache}->{'net.received.average'}->{key} . ":" . $_->{key} })) * 1024 * 8; + my $traffic_out = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{ $self->{connector}->{perfcounter_cache}->{'net.transmitted.average'}->{key} . ":" . $_->{key} })) * 1024 * 8; + + $data->{$entity_value}->{interfaces}->{ $_->{deviceInfo}->{label} }->{'net.received.average'} = $traffic_in; + $data->{$entity_value}->{interfaces}->{ $_->{deviceInfo}->{label} }->{'net.transmitted.average'} = $traffic_out; + } + } + + centreon::vmware::common::set_response(data => $data); +} + +1; From d6687ae2bf18f6cc7bc35fdb74d779655f7cf2a6 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 31 Jul 2020 15:11:57 +0200 Subject: [PATCH 256/447] indent --- .../vmware/src/centreon/vmware/cmddatastorehost.pm | 12 ++++++------ .../vmware/src/centreon/vmware/cmddatastoreusage.pm | 10 +++++----- connectors/vmware/src/centreon/vmware/common.pm | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm index ae1cbfd1f..974fc98c2 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastorehost.pm @@ -103,12 +103,12 @@ sub run { if (scalar(@$instances) > 0) { push @$query_perfs, { - entity => $entity_view, - metrics => [ - {label => 'datastore.totalReadLatency.average', instances => $instances}, - {label => 'datastore.totalWriteLatency.average', instances => $instances} - ] - }; + entity => $entity_view, + metrics => [ + { label => 'datastore.totalReadLatency.average', instances => $instances }, + { label => 'datastore.totalWriteLatency.average', instances => $instances } + ] + }; } } diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index c51d6b63b..4fe4598e9 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -54,24 +54,24 @@ sub run { my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); - + my $data = {}; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - + $data->{$entity_value} = { name => $entity_view->summary->name, accessible => $entity_view->summary->accessible }; next if (centreon::vmware::common::is_accessible(accessible => $entity_view->summary->accessible) == 0); - + # capacity 0... if ($entity_view->summary->capacity <= 0) { $data->{$entity_value}->{size} = 0; next; } - + # in Bytes $data->{$entity_value}->{size} = $entity_view->summary->capacity; $data->{$entity_value}->{free} = $entity_view->summary->freeSpace; - + my ($total_uncommited, $prct_uncommited); my $msg_uncommited = ''; if (defined($entity_view->summary->uncommitted)) { diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 984b8cfeb..93dcdb04a 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -499,14 +499,14 @@ sub search_entities { my $begin_views = []; foreach my $scope (['scope_datacenter', 'Datacenter'], ['scope_cluster', 'ClusterComputeResource'], ['scope_host', 'HostSystem']) { - if (defined($options{command}->{$$scope[0]}) && $options{command}->{$$scope[0]} ne '') { - my $filters = { name => qr/$options{command}->{$$scope[0]}/ }; + if (defined($options{command}->{$scope->[0]}) && $options{command}->{$scope->[0]} ne '') { + my $filters = { name => qr/$options{command}->{$scope->[0]}/ }; if (scalar(@$begin_views) > 0) { my $temp_views = []; while ((my $view = shift @$begin_views)) { my ($status, $views) = find_entity_views( connector => $options{command}->{connector}, - view_type => $$scope[1], + view_type => $scope->[1], properties => $properties, filter => $filters, begin_entity => $view, @@ -518,12 +518,12 @@ sub search_entities { } if (scalar(@$temp_views) == 0) { - set_response(code => 1, short_message => "Cannot find '$$scope[1]' object"); + set_response(code => 1, short_message => "Cannot find '$scope->[1]' object"); return undef; } push @$begin_views, @$temp_views; } else { - my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $$scope[1], properties => $properties, filter => $filters); + my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $scope->[1], properties => $properties, filter => $filters); # We quit. No scope find return undef if ($status <= 0); push @$begin_views, @$views; From b16acdb8d2120a170681a2362d7fc0fff6b30ebe Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 31 Jul 2020 15:51:32 +0200 Subject: [PATCH 257/447] add linked hosts to datastore usage --- .../src/centreon/vmware/cmddatastoreusage.pm | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index 4fe4598e9..6faf56d62 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -50,16 +50,42 @@ sub run { my $multiple = 0; my $filters = $self->build_filter(label => 'name', search_option => 'datastore_name', is_regexp => 'filter'); - my @properties = ('summary'); + my @properties = ('summary', 'host'); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'Datastore', properties => \@properties, filter => $filters); return if (!defined($result)); + my $mapped_host = {}; + my $host_array = []; + foreach my $entity_view (@$result) { + if (defined($entity_view->host)) { + foreach (@{$entity_view->host}) { + if (!defined($mapped_host->{ $_->{key}->{value} } )) { + push @$host_array, $_->{key}; + $mapped_host->{ $_->{key}->{value} } = '-'; + } + } + } + } + + if (scalar(@$host_array) > 0) { + my $result_hosts = centreon::vmware::common::get_views($self->{connector}, $host_array, ['name']); + foreach (@$result_hosts) { + $mapped_host->{ $_->{mo_ref}->{value} } = $_->{name}; + } + } + my $data = {}; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; - $data->{$entity_value} = { name => $entity_view->summary->name, accessible => $entity_view->summary->accessible }; + $data->{$entity_value} = { name => $entity_view->summary->name, accessible => $entity_view->summary->accessible, hosts => [] }; + if (defined($entity_view->host)) { + foreach (@{$entity_view->host}) { + push @{$data->{$entity_value}->{hosts}}, $mapped_host->{ $_->{key}->{value} }; + } + } + next if (centreon::vmware::common::is_accessible(accessible => $entity_view->summary->accessible) == 0); # capacity 0... From 08c1defb1ff6cec0f6ac18a72513e1fa16de1128 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 2 Nov 2020 12:07:24 +0100 Subject: [PATCH 258/447] chore(build): remove centos 6 support --- connectors/vmware/Jenkinsfile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index ffe9203e5..bfb07b467 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -18,12 +18,6 @@ stage('Source') { try { stage('Package') { - parallel 'centos6': { - node { - sh 'setup_centreon_build.sh' - sh './centreon-build/jobs/vmware/vmware-package.sh centos6' - } - }, 'centos7': { node { sh 'setup_centreon_build.sh' From cf0d87c8bdb4187198a675dad6fe47c0bca4795d Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Mon, 2 Nov 2020 12:11:43 +0100 Subject: [PATCH 259/447] fix(discovery): exclude vm object without uuid (not real vm) --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index e18321e6d..7874a80b3 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -153,6 +153,7 @@ sub run { foreach my $vm (@{$vms}) { next if ($vm->{'config.template'} eq 'true'); + next if (!defined($vm{uuid}) || $vm{uuid} eq ''); my %vm; $vm{type} = 'vm'; From e2a94a43ffa59fe53e569df7cae55531912ad6c4 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 2 Nov 2020 12:20:41 +0100 Subject: [PATCH 260/447] prepare version 3.2.0 --- connectors/vmware/changelog | 4 ++++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 3afebf429..85415dfec 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,7 @@ +2020-11-02 Quentin Garnier - 3.2.0 + * Enhancement: add 'net-vm' + * Enhancement: add 'hosts' attached to datastores for 'datastore-usage' + 2020-04-06 Quentin Garnier - 3.1.2 * Enhancement: add drs and das config enable 'cluster-status' * Enhancement: remove carriage return from vm annotation in discovery diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index e47e0413d..cde5ba31c 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.1.2'; +my $VERSION = '3.2.0'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 93dcdb04a..cea9dcea0 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.1.2'; + $manager_response->{vmware_connector_version} = '3.2.0'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 7f0bd9e4767dba125206152831128adbec632ae7 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 2 Nov 2020 12:21:38 +0100 Subject: [PATCH 261/447] prepare version 3.2.0 --- connectors/vmware/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 85415dfec..3b8c069c5 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,6 +1,7 @@ 2020-11-02 Quentin Garnier - 3.2.0 * Enhancement: add 'net-vm' * Enhancement: add 'hosts' attached to datastores for 'datastore-usage' + * Fix: remove vm without uuid for 'discovery' 2020-04-06 Quentin Garnier - 3.1.2 * Enhancement: add drs and das config enable 'cluster-status' From bd91aec7d5190f792623e7f1f53a8d2c4d276677 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 2 Nov 2020 13:26:46 +0100 Subject: [PATCH 262/447] chore(build): retrieve parralel statement in jenkinsfile --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index bfb07b467..1f0ac782e 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -18,7 +18,7 @@ stage('Source') { try { stage('Package') { - 'centos7': { + parallel 'centos7': { node { sh 'setup_centreon_build.sh' sh './centreon-build/jobs/vmware/vmware-package.sh centos7' From 0e2364143e5e4e714d9e42488d085dc2343c225e Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 3 Nov 2020 11:05:21 +0100 Subject: [PATCH 263/447] Fix #92 --- .../src/centreon/vmware/cmddiscovery.pm | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 7874a80b3..24877eda8 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -153,26 +153,26 @@ sub run { foreach my $vm (@{$vms}) { next if ($vm->{'config.template'} eq 'true'); - next if (!defined($vm{uuid}) || $vm{uuid} eq ''); - my %vm; + next if (!defined($vm->{uuid}) || $vm->{uuid} eq ''); + my $entry; - $vm{type} = 'vm'; - $vm{name} = $vm->{'config.name'}; - $vm{uuid} = $vm->{'config.uuid'}; - $vm{folder} = (defined($vm->parent) && $vm->parent->type eq 'Folder') ? $self->{paths}->{$vm->parent->value} : ''; - $vm{annotation} = $vm->{'config.annotation'}; - $vm{annotation} =~ s/\n/ /g if (defined($vm{annotation})); - $vm{os} = $vm->{'config.guestId'}; - $vm{hardware} = $vm->{'config.version'}; - $vm{guest_name} = $vm->{'guest.hostName'}; - $vm{guest_ip} = $vm->{'guest.ipAddress'}; - $vm{guest_state} = $vm->{'guest.guestState'}; - $vm{power_state} = $vm->{'runtime.powerState'}->val; - $vm{datacenter} = $datacenter->name; - $vm{cluster} = $cluster->name; - $vm{esx} = $esx->name; + $entry->{type} = 'vm'; + $entry->{name} = $vm->{'config.name'}; + $entry->{uuid} = $vm->{'config.uuid'}; + $entry->{folder} = (defined($vm->parent) && $vm->parent->type eq 'Folder') ? $self->{paths}->{$vm->parent->value} : ''; + $entry->{annotation} = $vm->{'config.annotation'}; + $entry->{annotation} =~ s/\n/ /g if (defined($entry->{annotation})); + $entry->{os} = $vm->{'config.guestId'}; + $entry->{hardware} = $vm->{'config.version'}; + $entry->{guest_name} = $vm->{'guest.hostName'}; + $entry->{guest_ip} = $vm->{'guest.ipAddress'}; + $entry->{guest_state} = $vm->{'guest.guestState'}; + $entry->{power_state} = $vm->{'runtime.powerState'}->val; + $entry->{datacenter} = $datacenter->name; + $entry->{cluster} = $cluster->name; + $entry->{esx} = $esx->name; - push @disco_data, \%vm; + push @disco_data, $entry; } } } From 28989082dfe08f537968dc67ecd060bf794a9104 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 3 Nov 2020 11:07:10 +0100 Subject: [PATCH 264/447] prepare release 3.2.1 --- connectors/vmware/changelog | 3 +++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 3b8c069c5..5b6843718 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2020-11-03 Quentin Garnier - 3.2.1 + * Fix: daemon cannot start (issue #92) + 2020-11-02 Quentin Garnier - 3.2.0 * Enhancement: add 'net-vm' * Enhancement: add 'hosts' attached to datastores for 'datastore-usage' diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index cde5ba31c..3d35f26ed 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.2.0'; +my $VERSION = '3.2.1'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index cea9dcea0..0773e1d87 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.2.0'; + $manager_response->{vmware_connector_version} = '3.2.1'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From d552ca476f88d15b93951a4aee92914b775098ea Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 3 Nov 2020 11:10:13 +0100 Subject: [PATCH 265/447] Fix #92 --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 24877eda8..91d71880d 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -153,7 +153,7 @@ sub run { foreach my $vm (@{$vms}) { next if ($vm->{'config.template'} eq 'true'); - next if (!defined($vm->{uuid}) || $vm->{uuid} eq ''); + next if (!defined($vm->{'config.uuid'}) || $vm->{'config.uuid'} eq ''); my $entry; $entry->{type} = 'vm'; From d6fd2a89ed75f8111647e76caa5a2354e34269d2 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Wed, 27 Oct 2021 14:07:52 +0200 Subject: [PATCH 266/447] new delivery workflow --- connectors/vmware/Jenkinsfile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 1f0ac782e..cd115506b 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -9,7 +9,7 @@ stage('Source') { env.VERSION = "${source.VERSION}" env.RELEASE = "${source.RELEASE}" if (env.BRANCH_NAME == 'master') { - withSonarQubeEnv('SonarQube') { + withSonarQubeEnv('SonarQubeDev') { sh './centreon-build/jobs/vmware/vmware-analysis.sh' } } @@ -22,18 +22,30 @@ try { node { sh 'setup_centreon_build.sh' sh './centreon-build/jobs/vmware/vmware-package.sh centos7' + archiveArtifacts artifacts: 'rpms-centos7.tar.gz' + stash name: "rpms-centos7", includes: 'output/noarch/*.rpm' + sh 'rm -rf output' } }, 'centos8': { node { sh 'setup_centreon_build.sh' sh './centreon-build/jobs/vmware/vmware-package.sh centos8' + archiveArtifacts artifacts: 'rpms-centos8.tar.gz' + stash name: "rpms-centos8", includes: 'output/noarch/*.rpm' + sh 'rm -rf output' } } if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { error('Package stage failure.'); } } + stage('Delivery') { + sh 'setup_centreon_build.sh' + unstash "rpms-centos7" + unstash "rpms-centos8" + sh './centreon-build/jobs/vmware/vmware-delivery.sh' + } } catch(e) { if (env.BRANCH_NAME == 'master') { slackSend channel: "#monitoring-metrology", color: "#F30031", message: "*FAILURE*: `CENTREON VMWARE` <${env.BUILD_URL}|build #${env.BUILD_NUMBER}> on branch ${env.BRANCH_NAME}\n*COMMIT*: by ${source.COMMITTER}\n*INFO*: ${e}" From d844a9479da59b0927def655aad87496f4dadc15 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Wed, 27 Oct 2021 14:26:46 +0200 Subject: [PATCH 267/447] fix node --- connectors/vmware/Jenkinsfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index cd115506b..afb63d9ae 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -41,10 +41,12 @@ try { } } stage('Delivery') { - sh 'setup_centreon_build.sh' - unstash "rpms-centos7" - unstash "rpms-centos8" - sh './centreon-build/jobs/vmware/vmware-delivery.sh' + node { + sh 'setup_centreon_build.sh' + unstash "rpms-centos7" + unstash "rpms-centos8" + sh './centreon-build/jobs/vmware/vmware-delivery.sh' + } } } catch(e) { if (env.BRANCH_NAME == 'master') { From 045042e2c8bc56479435a75f487f282a1d7b0dc1 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 15 Dec 2021 15:26:27 +0100 Subject: [PATCH 268/447] wip --- .../src/centreon/script/centreon_vmware.pm | 4 +- .../vmware/src/centreon/vmware/cmdlicenses.pm | 59 ++++++++ .../src/centreon/vmware/cmdstoragehost.pm | 134 ++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 connectors/vmware/src/centreon/vmware/cmdlicenses.pm create mode 100644 connectors/vmware/src/centreon/vmware/cmdstoragehost.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 3d35f26ed..70e2a6ed9 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.2.1'; +my $VERSION = '3.2.2'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( @@ -74,6 +74,7 @@ my @load_modules = ( 'centreon::vmware::cmddiscovery', 'centreon::vmware::cmdgetmap', 'centreon::vmware::cmdhealthhost', + 'centreon::vmware::cmdlicenses', 'centreon::vmware::cmdlimitvm', 'centreon::vmware::cmdlistclusters', 'centreon::vmware::cmdlistdatacenters', @@ -89,6 +90,7 @@ my @load_modules = ( 'centreon::vmware::cmdstatuscluster', 'centreon::vmware::cmdstatushost', 'centreon::vmware::cmdstatusvm', + 'centreon::vmware::cmdstoragehost', 'centreon::vmware::cmdswaphost', 'centreon::vmware::cmdswapvm', 'centreon::vmware::cmdthinprovisioningvm', diff --git a/connectors/vmware/src/centreon/vmware/cmdlicenses.pm b/connectors/vmware/src/centreon/vmware/cmdlicenses.pm new file mode 100644 index 000000000..acab59985 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdlicenses.pm @@ -0,0 +1,59 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdlicenses; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'licenses'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + return 0; +} + +sub run { + my $self = shift; + + my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->licenseManager); + + my $data = {}; + if (defined($entries->licenses)) { + foreach my $license (@{$entries->licenses}) { + use Data::Dumper; + print Data::Dumper::Dumper($license); + } + } + + centreon::vmware::common::set_response(data => $data); +} + +1; diff --git a/connectors/vmware/src/centreon/vmware/cmdstoragehost.pm b/connectors/vmware/src/centreon/vmware/cmdstoragehost.pm new file mode 100644 index 000000000..137441001 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdstoragehost.pm @@ -0,0 +1,134 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdstoragehost; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'storagehost'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + centreon::vmware::common::set_response(code => 100, short_message => "Argument error: esx hostname cannot be null"); + return 1; + } + + return 0; +} + +sub run { + my $self = shift; + + my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); + my @properties = ('name', 'runtime.connectionState', 'runtime.inMaintenanceMode', 'configManager.storageSystem'); + my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); + return if (!defined($result)); + + my %host_names = (); + my @host_array = (); + my $data = {}; + foreach my $entity_view (@$result) { + my $entity_value = $entity_view->{mo_ref}->{value}; + + $data->{$entity_value} = { + name => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + inMaintenanceMode => $entity_view->{'runtime.inMaintenanceMode'}, + }; + + next if (centreon::vmware::common::is_connected(state => $entity_view->{'runtime.connectionState'}->val) == 0); + next if (centreon::vmware::common::is_maintenance(maintenance => $entity_view->{'runtime.inMaintenanceMode'}) == 0); + + if (defined($entity_view->{'configManager.storageSystem'})) { + push @host_array, $entity_view->{'configManager.storageSystem'}; + $host_names{ $entity_view->{'configManager.storageSystem'}->{value} } = $entity_value; + } + } + + if (scalar(@host_array) == 0) { + centreon::vmware::common::set_response(data => $data); + return ; + } + + @properties = ('storageDeviceInfo'); + my $result2 = centreon::vmware::common::get_views($self->{connector}, \@host_array, \@properties); + return if (!defined($result2)); + + foreach my $entity (@$result2) { + my $host_id = $host_names{ $entity->{mo_ref}->{value} }; + + if (defined($entity->storageDeviceInfo->hostBusAdapter)) { + $data->{$host_id}->{adapters} = []; + foreach my $dev (@{$entity->storageDeviceInfo->hostBusAdapter}) { + push @{$data->{$host_id}->{adapters}}, { + name => $dev->device, + status => lc($dev->status) + }; + } + } + + if (defined($entity->storageDeviceInfo->scsiLun)) { + $data->{$host_id}->{luns} = []; + foreach my $scsi (@{$entity->storageDeviceInfo->scsiLun}) { + my $name = $scsi->deviceName; + if (defined($scsi->{displayName})) { + $name = $scsi->displayName; + } elsif (defined($scsi->{canonicalName})) { + $name = $scsi->canonicalName; + } + + push @{$data->{$host_id}->{luns}}, { + name => $name, + operational_states => $scsi->operationalState + }; + } + } + + if (defined($entity->storageDeviceInfo->{multipathInfo})) { + $data->{$host_id}->{paths} = []; + foreach my $lun (@{$entity->storageDeviceInfo->multipathInfo->lun}) { + foreach my $path (@{$lun->path}) { + my $state = $path->pathState; + $state = $path->state if (defined($path->{state})); + push @{$data->{$host_id}->{paths}}, { + name => $path->name, + state => lc($state) + }; + } + } + } + } + + centreon::vmware::common::set_response(data => $data); +} + +1; From 48e8de1efc871439027e7c5724ad5d0eb7bc1c48 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 16 Dec 2021 09:33:59 +0100 Subject: [PATCH 269/447] manage case insensitive --- .../src/centreon/script/centreon_vmware.pm | 71 ++++++++++++------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 70e2a6ed9..c1063cb99 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -162,6 +162,11 @@ sub init { $self->{centreon_vmware_config} = {%{$self->{centreon_vmware_default_config}}, %centreon_vmware_config}; + foreach my $name (keys %{$self->{centreon_vmware_config}->{vsphere_server}}) { + my $iname = lc($name); + $self->{centreon_vmware_config}->{vsphere_server}->{$iname} = delete $self->{centreon_vmware_config}->{vsphere_server}->{$name}; + } + ##### Load modules $self->load_module(@load_modules); @@ -354,20 +359,27 @@ sub request_dynamic { my $container = md5_hex($options{result}->{vsphere_address} . $options{result}->{vsphere_username} . $options{result}->{vsphere_password}); # Need to create fork if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$container})) { - $self->{centreon_vmware_config}->{vsphere_server}->{$container} = { url => 'https://' . $options{result}->{vsphere_address} . '/sdk', - username => $options{result}->{vsphere_username}, - password => $options{result}->{vsphere_password}, - last_request => time() }; - $self->{logger}->writeLogError(sprintf("Dynamic creation: identity = %s [address: %s] [username: %s] [password: %s]", - $container, $options{result}->{vsphere_address}, $options{result}->{vsphere_username}, $options{result}->{vsphere_password})); + $self->{centreon_vmware_config}->{vsphere_server}->{$container} = { + url => 'https://' . $options{result}->{vsphere_address} . '/sdk', + username => $options{result}->{vsphere_username}, + password => $options{result}->{vsphere_password}, + last_request => time() + }; + $self->{logger}->writeLogError( + sprintf( + "Dynamic creation: identity = %s [address: %s] [username: %s] [password: %s]", + $container, $options{result}->{vsphere_address}, $options{result}->{vsphere_username}, $options{result}->{vsphere_password} + ) + ); $centreon_vmware->create_vsphere_child(vsphere_name => $container, dynamic => 1); } - return if ($self->waiting_ready(container => $container, manager => $options{manager}, - identity => $options{identity}) == 0); - + return if ($self->waiting_ready( + container => $container, manager => $options{manager}, + identity => $options{identity}) == 0); + $self->{centreon_vmware_config}->{vsphere_server}->{$container}->{last_request} = time(); - + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; my $msg = zmq_msg_init_data("server-" . $container); zmq_msg_send($msg, $frontend, $flag); @@ -395,36 +407,39 @@ sub request { centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } - if (!defined($self->{modules_registry}->{$result->{command}})) { + if (!defined($self->{modules_registry}->{ $result->{command} })) { centreon::vmware::common::set_response(code => 1, short_message => "Unknown method name '$result->{command}'"); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } - if ($self->{modules_registry}->{$result->{command}}->checkArgs(manager => $options{manager}, - arguments => $result)) { + if ($self->{modules_registry}->{ $result->{command} }->checkArgs( + manager => $options{manager}, + arguments => $result)) { centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } - + # Mode dynamic if (defined($result->{vsphere_address}) && $result->{vsphere_address} ne '') { $self->request_dynamic(result => $result, %options); return ; } - - if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$result->{container}})) { + + $result->{container} = lc($result->{container}); + if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{ $result->{container} })) { centreon::vmware::common::set_response(code => 1, short_message => "Unknown container name '$result->{container}'"); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } - return if ($self->waiting_ready(container => $result->{container}, manager => $options{manager}, - identity => $options{identity}) == 0); - - $self->{counter_stats}->{$result->{container}}++; + return if ($self->waiting_ready( + container => $result->{container}, manager => $options{manager}, + identity => $options{identity}) == 0); + $self->{counter_stats}->{ $result->{container} }++; + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; - my $msg = zmq_msg_init_data("server-" . $result->{container}); + my $msg = zmq_msg_init_data('server-' . $result->{container}); zmq_msg_send($msg, $frontend, $flag); zmq_msg_close($msg); $msg = zmq_msg_init_data('REQCLIENT ' . $options{data}); @@ -447,9 +462,11 @@ sub repserver { $result->{identity} =~ /^client-(.*)$/; my $identity = 'client-' . pack('H*', $1); - - centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, - identity => $identity, force_response => $options{data}); + + centreon::vmware::common::response( + token => 'RESPSERVER', endpoint => $frontend, + identity => $identity, force_response => $options{data} + ); } sub router_event { @@ -459,12 +476,12 @@ sub router_event { zmq_msg_recv($msg, $frontend, ZMQ_DONTWAIT); my $identity = zmq_msg_data($msg); zmq_msg_close($msg); - + $msg = zmq_msg_init(); zmq_msg_recv($msg, $frontend, ZMQ_DONTWAIT); my $data = zmq_msg_data($msg); zmq_msg_close($msg); - + centreon::vmware::common::init_response(); if ($centreon_vmware->{stop} != 0) { # We quit so we say we're leaving ;) @@ -518,7 +535,7 @@ sub create_vsphere_child { modules_registry => $self->{modules_registry}, config => $self->{centreon_vmware_config}, logger => $self->{logger}, - vsan_enabled => $self->{vsan_enabled}, + vsan_enabled => $self->{vsan_enabled} ); $connector->run(); exit(0); From 819835640d25eb931efbe1932921bfb76802c592 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 16 Dec 2021 10:55:40 +0100 Subject: [PATCH 270/447] wip --- .../src/centreon/script/centreon_vmware.pm | 1 + .../vmware/src/centreon/vmware/cmdbase.pm | 8 +- .../src/centreon/vmware/cmdcpucluster.pm | 98 +++++++++++++++++++ .../vmware/src/centreon/vmware/cmdcpuhost.pm | 27 +++-- .../src/centreon/vmware/cmddatastoreusage.pm | 4 + .../vmware/src/centreon/vmware/common.pm | 1 + 6 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 connectors/vmware/src/centreon/vmware/cmdcpucluster.pm diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index c1063cb99..15a1599c5 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -61,6 +61,7 @@ my @load_modules = ( 'centreon::vmware::cmdalarmdatacenter', 'centreon::vmware::cmdalarmhost', 'centreon::vmware::cmdcountvmhost', + 'centreon::vmware::cmdcpucluster', 'centreon::vmware::cmdcpuhost', 'centreon::vmware::cmdcpuvm', 'centreon::vmware::cmddatastorecountvm', diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index 9cbf1659e..5aea8144e 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -31,7 +31,7 @@ sub new { $self->{logger} = $options{logger}; $self->{global_case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; - + return $self; } @@ -55,7 +55,7 @@ sub class_handle_ALRM { sub handle_ALRM { my $self = shift; - + $self->{logger}->writeLogError('Child process autokill!!'); exit(0); } @@ -80,12 +80,12 @@ sub set_connector { sub initArgs { my ($self, %options) = @_; - + foreach (keys %{$options{arguments}}) { $self->{$_} = $options{arguments}->{$_}; } centreon::vmware::common::init_response(identity => $options{arguments}->{identity}); - + if ($self->{global_case_insensitive} == 0 && defined($self->{case_insensitive})) { $self->{global_case_insensitive} = 1; } diff --git a/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm b/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm new file mode 100644 index 000000000..05f4e5742 --- /dev/null +++ b/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm @@ -0,0 +1,98 @@ +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package centreon::vmware::cmdcpucluster; + +use base qw(centreon::vmware::cmdbase); + +use strict; +use warnings; +use centreon::vmware::common; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(%options); + bless $self, $class; + + $self->{commandName} = 'cpucluster'; + + return $self; +} + +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{cluster_name}) && $options{arguments}->{cluster_name} eq '') { + centreon::vmware::common::set_response(code => 100, short_message => 'Argument error: cluster name cannot be null'); + return 1; + } + + return 0; +} + +sub run { + my $self = shift; + + if (!($self->{connector}->{perfcounter_speriod} > 0)) { + centreon::vmware::common::set_response(code => -1, short_message => "Can't retrieve perf counters"); + return ; + } + + my $filters = $self->build_filter(label => 'name', search_option => 'cluster_name', is_regexp => 'filter'); + my @properties = ('name'); + my $views = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); + return if (!defined($views)); + + my @instances = ('*'); + my $values = centreon::vmware::common::generic_performance_values_historic( + $self->{connector}, + $views, + [ + { label => 'cpu.usage.average', 'instances' => \@instances}, + { label => 'cpu.usagemhz.average', 'instances' => \@instances} + ], + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, + time_shift => $self->{time_shift}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1 + ); + return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); + + my $interval_min = centreon::vmware::common::get_interval_min( + speriod => $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, + time_shift => $self->{time_shift} + ); + + my $data = {}; + foreach my $view (@$views) { + my $entity_value = $view->{mo_ref}->{value}; + $data->{$entity_value} = { name => $view->{name} }; + + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"} * 0.01)); + my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"})); + + $data->{$entity_value}->{'interval_min'} = $interval_min; + $data->{$entity_value}->{'cpu.usage.average'} = $total_cpu_average; + $data->{$entity_value}->{'cpu.usagemhz.average'} = $total_cpu_mhz_average; + } + + centreon::vmware::common::set_response(data => $data); +} + +1; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm index 31c60739f..508289e34 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuhost.pm @@ -59,18 +59,25 @@ sub run { return if (!defined($result)); my @instances = ('*'); - my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, - $result, - [{'label' => 'cpu.usage.average', 'instances' => \@instances}, - {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}], - $self->{connector}->{perfcounter_speriod}, - sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, - skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); + my $values = centreon::vmware::common::generic_performance_values_historic( + $self->{connector}, + $result, + [ + { label => 'cpu.usage.average', 'instances' => \@instances}, + { label => 'cpu.usagemhz.average', 'instances' => \@instances} + ], + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, + time_shift => $self->{time_shift}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1 + ); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); - my $interval_min = centreon::vmware::common::get_interval_min(speriod => $self->{connector}->{perfcounter_speriod}, - sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}); - + my $interval_min = centreon::vmware::common::get_interval_min( + speriod => $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift} + ); + my $data = {}; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; diff --git a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm index 6faf56d62..1c38e06f0 100644 --- a/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/vmware/cmddatastoreusage.pm @@ -88,6 +88,10 @@ sub run { next if (centreon::vmware::common::is_accessible(accessible => $entity_view->summary->accessible) == 0); + if (defined($self->{refresh})) { + $entity_view->RefreshDatastore(); + } + # capacity 0... if ($entity_view->summary->capacity <= 0) { $data->{$entity_value}->{size} = 0; diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 0773e1d87..f67468962 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -486,6 +486,7 @@ sub cache_perf_counters { $obj_vmware->{perfcounter_speriod} = 20; } }; + if ($@) { $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); return 1; From b699e5e064aab1da832aabf574f1821327675e07 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 16 Dec 2021 11:37:29 +0100 Subject: [PATCH 271/447] wip --- connectors/vmware/src/centreon/vmware/common.pm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index f67468962..c26195743 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -553,7 +553,13 @@ sub search_entities { } return $results; } else { - my ($status, $views) = find_entity_views(connector => $options{command}->{connector}, view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); + my ($status, $views) = find_entity_views( + connector => $options{command}->{connector}, + view_type => $options{view_type}, + properties => $options{properties}, + filter => $options{filter}, + empty_continue => $options{command}->{empty_continue} + ); return $views; } } @@ -585,6 +591,9 @@ sub find_entity_views { } if (!defined($entity_views) || scalar(@$entity_views) == 0) { my $status = 0; + if (defined($options{empty_continue})) { + return (1, []); + } if (!defined($options{output_message}) || $options{output_message} != 0) { set_response(code => 1, short_message => "Cannot find '$options{view_type}' object"); } From 095a34431a66333430c9cfe3c612b0deac8e1088 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 16 Dec 2021 14:06:48 +0100 Subject: [PATCH 272/447] wip --- connectors/vmware/changelog | 7 +++++++ .../vmware/src/centreon/vmware/cmdhealthhost.pm | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 5b6843718..dd350aa84 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,10 @@ +2021-12-XX Quentin Garnier - 3.2.2 + * Enhancement: add 'storage-host' + * Enhancement: add 'cpu-cluster' (issue #90) + * Enhancement: add refresh capability for datastore-usage (issue #96) + * Enhancement: container label in configuration is case-insensitive (issue #83) + * Enhancement: add capability to use empty-continue option (issue #77) + 2020-11-03 Quentin Garnier - 3.2.1 * Fix: daemon cannot start (issue #92) diff --git a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm index b47868de1..3b0771232 100644 --- a/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm +++ b/connectors/vmware/src/centreon/vmware/cmdhealthhost.pm @@ -49,8 +49,10 @@ sub run { my $self = shift; my $filters = $self->build_filter(label => 'name', search_option => 'esx_hostname', is_regexp => 'filter'); - my @properties = ('name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', - 'runtime.connectionState'); + my @properties = ( + 'name', 'runtime.healthSystemRuntime.hardwareStatusInfo', 'runtime.healthSystemRuntime.systemHealthInfo.numericSensorInfo', + 'runtime.connectionState' + ); my $result = centreon::vmware::common::search_entities(command => $self, view_type => 'HostSystem', properties => \@properties, filter => $filters); return if (!defined($result)); @@ -95,7 +97,8 @@ sub run { foreach (@$numericSensorInfo) { push @{$data->{$entity_value}->{sensor_info}}, { status => $_->healthState->key, - type => $_->sensorType, name => $_->name, summary => $_->healthState->summary, + type => $_->sensorType, name => $_->name, + summary => $_->healthState->summary, current_reading => $_->currentReading, power10 => $_->unitModifier, unit => $_->baseUnits @@ -103,7 +106,7 @@ sub run { } } } - + centreon::vmware::common::set_response(data => $data); } From 74a7bfef88fab67a9d93ee916bd144f24add95cd Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 17 Dec 2021 15:52:40 +0100 Subject: [PATCH 273/447] wip --- .../src/centreon/vmware/cmdcpucluster.pm | 11 ++++---- .../vmware/src/centreon/vmware/cmdcpuvm.pm | 28 +++++++++++-------- .../src/centreon/vmware/cmddiscovery.pm | 8 ++++-- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm b/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm index 05f4e5742..ed4127e10 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpucluster.pm @@ -58,13 +58,12 @@ sub run { my $views = centreon::vmware::common::search_entities(command => $self, view_type => 'ClusterComputeResource', properties => \@properties, filter => $filters); return if (!defined($views)); - my @instances = ('*'); my $values = centreon::vmware::common::generic_performance_values_historic( $self->{connector}, - $views, + $views, [ - { label => 'cpu.usage.average', 'instances' => \@instances}, - { label => 'cpu.usagemhz.average', 'instances' => \@instances} + { label => 'cpu.usage.average', instances => [''] }, + { label => 'cpu.usagemhz.average', instances => [''] } ], $self->{connector}->{perfcounter_speriod}, sampling_period => $self->{sampling_period}, @@ -84,8 +83,8 @@ sub run { my $entity_value = $view->{mo_ref}->{value}; $data->{$entity_value} = { name => $view->{name} }; - my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"} * 0.01)); - my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{$self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{'key'} . ":"})); + my $total_cpu_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{ $self->{connector}->{perfcounter_cache}->{'cpu.usage.average'}->{key} . ':' } * 0.01)); + my $total_cpu_mhz_average = centreon::vmware::common::simplify_number(centreon::vmware::common::convert_number($values->{$entity_value}->{ $self->{connector}->{perfcounter_cache}->{'cpu.usagemhz.average'}->{key} . ':' })); $data->{$entity_value}->{'interval_min'} = $interval_min; $data->{$entity_value}->{'cpu.usage.average'} = $total_cpu_average; diff --git a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm index cb7ef2d65..a8de65599 100644 --- a/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm +++ b/connectors/vmware/src/centreon/vmware/cmdcpuvm.pm @@ -66,23 +66,29 @@ sub run { return if (!defined($result)); my @instances = ('*'); - my $values = centreon::vmware::common::generic_performance_values_historic($self->{connector}, - $result, - [{'label' => 'cpu.usage.average', 'instances' => \@instances}, - {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, - {'label' => 'cpu.ready.summation', 'instances' => \@instances}], - $self->{connector}->{perfcounter_speriod}, - sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, - skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); + my $values = centreon::vmware::common::generic_performance_values_historic( + $self->{connector}, + $result, + [ + {'label' => 'cpu.usage.average', 'instances' => \@instances}, + {'label' => 'cpu.usagemhz.average', 'instances' => \@instances}, + {'label' => 'cpu.ready.summation', 'instances' => \@instances} + ], + $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1 + ); return if (centreon::vmware::common::performance_errors($self->{connector}, $values) == 1); my $interval_sec = $self->{connector}->{perfcounter_speriod}; if (defined($self->{sampling_period}) && $self->{sampling_period} ne '') { $interval_sec = $self->{sampling_period}; } - my $interval_min = centreon::vmware::common::get_interval_min(speriod => $self->{connector}->{perfcounter_speriod}, - sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift}); - + my $interval_min = centreon::vmware::common::get_interval_min( + speriod => $self->{connector}->{perfcounter_speriod}, + sampling_period => $self->{sampling_period}, time_shift => $self->{time_shift} + ); + my $data = {}; foreach my $entity_view (@$result) { my $entity_value = $entity_view->{mo_ref}->{value}; diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 91d71880d..19ce44e64 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -112,9 +112,11 @@ sub run { foreach my $cluster (@$clusters) { next if (!$cluster->{'host'}); - my @properties = ('name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', + my @properties = ( + 'name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', - 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState'); + 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState' + ); my $esxs = centreon::vmware::common::get_views($self->{connector}, \@{$cluster->host}, \@properties); next if (!defined($esxs)); @@ -122,7 +124,7 @@ sub run { foreach my $esx (@$esxs) { my %esx; - $esx{type} = "esx"; + $esx{type} = 'esx'; $esx{name} = $esx->name; $esx{os} = $esx->{'config.product.productLineId'} . ' ' . $esx->{'config.product.version'}; $esx{hardware} = $esx->{'hardware.systemInfo.vendor'} . ' ' . $esx->{'hardware.systemInfo.model'}; From c7f220e86fb7b83a8c1bc8bb7f6544ec8e6316a2 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 21 Dec 2021 11:01:29 +0100 Subject: [PATCH 274/447] wip --- connectors/vmware/src/centreon/vmware/cmdlicenses.pm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmdlicenses.pm b/connectors/vmware/src/centreon/vmware/cmdlicenses.pm index acab59985..5d0c7db14 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlicenses.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlicenses.pm @@ -48,8 +48,16 @@ sub run { my $data = {}; if (defined($entries->licenses)) { foreach my $license (@{$entries->licenses}) { - use Data::Dumper; - print Data::Dumper::Dumper($license); + $data->{ $license->{name} } = { + total => $license->{total}, + used => $license->{used}, + edition => $license->{editionKey} + }; + foreach my $prop (@{$license->{properties}}) { + if ($prop->{key} eq 'expirationMinutes') { + $data->{ $license->{name} }->{expiration_minutes} = $prop->{value}; + } + } } } From da2825eaefc725242ee804f5277917e73cefbfcf Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 21 Dec 2021 11:43:31 +0100 Subject: [PATCH 275/447] wip --- connectors/vmware/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index dd350aa84..40d5c56eb 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,6 +1,7 @@ -2021-12-XX Quentin Garnier - 3.2.2 +2021-12-21 Quentin Garnier - 3.2.2 * Enhancement: add 'storage-host' * Enhancement: add 'cpu-cluster' (issue #90) + * Enhancement: add 'licenses' * Enhancement: add refresh capability for datastore-usage (issue #96) * Enhancement: container label in configuration is case-insensitive (issue #83) * Enhancement: add capability to use empty-continue option (issue #77) From 7921799bdb0305a6e82d598f9c757e296d8ea6b0 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 21 Dec 2021 11:44:16 +0100 Subject: [PATCH 276/447] wip --- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index c26195743..8462aa3ca 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.2.1'; + $manager_response->{vmware_connector_version} = '3.2.2'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From b754dd0bbc53ac36c3ea7d18cddbdd4a265e4bf2 Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Tue, 12 Apr 2022 13:33:51 +0100 Subject: [PATCH 277/447] add resources-agents from contrib repo --- connectors/vmware/Jenkinsfile | 10 ++++++ connectors/vmware/ci/debian/control | 18 ++++++++++ connectors/vmware/ci/debian/copyright | 29 +++++++++++++++ connectors/vmware/ci/debian/install | 4 +++ connectors/vmware/ci/debian/rules | 6 ++++ connectors/vmware/ci/debian/source/format | 1 + .../vmware/ci/scripts/vmware-deb-package.sh | 36 +++++++++++++++++++ 7 files changed, 104 insertions(+) create mode 100644 connectors/vmware/ci/debian/control create mode 100644 connectors/vmware/ci/debian/copyright create mode 100644 connectors/vmware/ci/debian/install create mode 100755 connectors/vmware/ci/debian/rules create mode 100644 connectors/vmware/ci/debian/source/format create mode 100755 connectors/vmware/ci/scripts/vmware-deb-package.sh diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index afb63d9ae..5fca635cf 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -35,6 +35,16 @@ try { stash name: "rpms-centos8", includes: 'output/noarch/*.rpm' sh 'rm -rf output' } + }, + 'Debian bullseye packaging and signing': { + node { + dir('centreon-vmware') { + checkout scm + } + sh 'docker run -i --entrypoint "/src/centreon-vmware/ci/scripts/vmware-deb-package.sh" -w "/src" -v "$PWD:/src" -e "DISTRIB=Debian11" -e "VERSION=$VERSION" -e "RELEASE=$RELEASE" registry.centreon.com/centreon-debian11-dependencies:22.04' + stash name: 'Debian11', includes: 'Debian11/*.deb' + archiveArtifacts artifacts: "Debian11/*" + } } if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { error('Package stage failure.'); diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control new file mode 100644 index 000000000..f14c0aad7 --- /dev/null +++ b/connectors/vmware/ci/debian/control @@ -0,0 +1,18 @@ +Source: centreon-plugin-virtualization-vmware-daemon +Section: net +Priority: optional +Maintainer: Luiz Costa +Build-Depends: debhelper-compat (= 12) +Standards-Version: 4.5.0 +Homepage: https://www.centreon.com + +Package: centreon-plugin-virtualization-vmware-daemon +Architecture: all +Depends: ${misc:Depends}, + ${shlibs:Depends}, + libio-socket-inet6-perl, + libjson-xs-perl, + liblwp-protocol-https-perl, + libzmq-constants-perl, + zmq-libzmq4-perl +Description: Perl daemon to monitor VSphere Infrastructure diff --git a/connectors/vmware/ci/debian/copyright b/connectors/vmware/ci/debian/copyright new file mode 100644 index 000000000..9d1ae47d8 --- /dev/null +++ b/connectors/vmware/ci/debian/copyright @@ -0,0 +1,29 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: centreon-plugin-virtualization-vmware-daemon +Upstream-Contact: Luiz Costa +Source: https://www.centreon.com + +Files: * +Copyright: 2022 Centreon +License: Apache-2.0 + +Files: debian/* +Copyright: 2022 Centreon +License: Apache-2.0 + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + https://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + On Debian systems, the complete text of the Apache version 2.0 license + can be found in "/usr/share/common-licenses/Apache-2.0". + diff --git a/connectors/vmware/ci/debian/install b/connectors/vmware/ci/debian/install new file mode 100644 index 000000000..b10fd273d --- /dev/null +++ b/connectors/vmware/ci/debian/install @@ -0,0 +1,4 @@ +centreon_vmware.pl usr/bin +contrib/debian/centreon_vmware-systemd lib/systemd/system/centreon_vmware +contrib/config/centreon_vmware-conf.pm etc/centreon/centreon_vmware.pm +centreon/* usr/share/perl5/centreon diff --git a/connectors/vmware/ci/debian/rules b/connectors/vmware/ci/debian/rules new file mode 100755 index 000000000..d8309f67d --- /dev/null +++ b/connectors/vmware/ci/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ diff --git a/connectors/vmware/ci/debian/source/format b/connectors/vmware/ci/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/connectors/vmware/ci/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh new file mode 100755 index 000000000..15d012602 --- /dev/null +++ b/connectors/vmware/ci/scripts/vmware-deb-package.sh @@ -0,0 +1,36 @@ +#!/bin/sh +set -ex + +if [ -z "$VERSION" -o -z "$RELEASE" -o -z "$DISTRIB" ] ; then + echo "You need to specify VERSION / RELEASE / DISTRIB variables" + exit 1 +fi + +echo "################################################## PACKAGING COLLECT ##################################################" + +AUTHOR="Luiz Costa" +AUTHOR_EMAIL="me@luizgustavo.pro.br" + +if [ -d /build ]; then + rm -rf /build +fi +mkdir -p /build +cd /build + +mkdir -p /build/centreon-plugin-virtualization-vmware-daemon +(cd /src && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz +cp -rv /src/centreon-vmware /build/ +cp -rv /src/centreon-vmware/ci/debian /build/centreon-plugin-virtualization-vmware-daemon/ + +ls -lart +cd /build/centreon-plugin-virtualization-vmware-daemon +debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "$VERSION" -y -r "$RELEASE" +debuild-pbuilder +cd /build + +if [ -d "$DISTRIB" ] ; then + rm -rf "$DISTRIB" +fi +mkdir $DISTRIB +mv /build/*.deb $DISTRIB/ +mv /build/$DISTRIB/*.deb /src From 7a89060462c7db4f5fc95451a7714df45d06f20f Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Wed, 13 Apr 2022 11:44:15 +0100 Subject: [PATCH 278/447] fix dependencies --- connectors/vmware/ci/debian/contrib/centreon_vmware | 1 + connectors/vmware/ci/debian/contrib/centreon_vmware.pm | 1 + connectors/vmware/ci/debian/install | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 120000 connectors/vmware/ci/debian/contrib/centreon_vmware create mode 120000 connectors/vmware/ci/debian/contrib/centreon_vmware.pm diff --git a/connectors/vmware/ci/debian/contrib/centreon_vmware b/connectors/vmware/ci/debian/contrib/centreon_vmware new file mode 120000 index 000000000..d2806142a --- /dev/null +++ b/connectors/vmware/ci/debian/contrib/centreon_vmware @@ -0,0 +1 @@ +../../../contrib/debian/centreon_vmware-systemd \ No newline at end of file diff --git a/connectors/vmware/ci/debian/contrib/centreon_vmware.pm b/connectors/vmware/ci/debian/contrib/centreon_vmware.pm new file mode 120000 index 000000000..2f0885ece --- /dev/null +++ b/connectors/vmware/ci/debian/contrib/centreon_vmware.pm @@ -0,0 +1 @@ +../../../contrib/config/centreon_vmware-conf.pm \ No newline at end of file diff --git a/connectors/vmware/ci/debian/install b/connectors/vmware/ci/debian/install index b10fd273d..62e8bab0b 100644 --- a/connectors/vmware/ci/debian/install +++ b/connectors/vmware/ci/debian/install @@ -1,4 +1,4 @@ centreon_vmware.pl usr/bin -contrib/debian/centreon_vmware-systemd lib/systemd/system/centreon_vmware -contrib/config/centreon_vmware-conf.pm etc/centreon/centreon_vmware.pm +debian/contrib/centreon_vmware lib/systemd/system +debian/contrib/centreon_vmware.pm etc/centreon centreon/* usr/share/perl5/centreon From 9c96e8eccc42d2ea02473e6331e4613d628be823 Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Wed, 13 Apr 2022 11:59:25 +0100 Subject: [PATCH 279/447] change name and config service --- ...ntreon-plugin-virtualization-vmware-daemon.install} | 0 ...ntreon-plugin-virtualization-vmware-daemon.postinst | 10 ++++++++++ 2 files changed, 10 insertions(+) rename connectors/vmware/ci/debian/{install => centreon-plugin-virtualization-vmware-daemon.install} (100%) create mode 100644 connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst diff --git a/connectors/vmware/ci/debian/install b/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.install similarity index 100% rename from connectors/vmware/ci/debian/install rename to connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.install diff --git a/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst b/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst new file mode 100644 index 000000000..93e80a677 --- /dev/null +++ b/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ "$1" = "configure" ] ; then + + systemctl daemon-reload + systemctl enable centreon_vmware.service + systemctl restart centreon_vmware.service + +fi +exit 0 \ No newline at end of file From 1b5817611f897ebe25f953dac38a0e4987447d6e Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Wed, 13 Apr 2022 12:11:06 +0100 Subject: [PATCH 280/447] fix path renames --- connectors/vmware/ci/scripts/vmware-deb-package.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh index 15d012602..ca7d08ec7 100755 --- a/connectors/vmware/ci/scripts/vmware-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deb-package.sh @@ -16,10 +16,9 @@ if [ -d /build ]; then fi mkdir -p /build cd /build - -mkdir -p /build/centreon-plugin-virtualization-vmware-daemon -(cd /src && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz cp -rv /src/centreon-vmware /build/ +mv -v /build/centreon-vmware /build/centreon-plugin-virtualization-vmware-daemon +(cd /src && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz cp -rv /src/centreon-vmware/ci/debian /build/centreon-plugin-virtualization-vmware-daemon/ ls -lart From 9686fc91669b5fadd36af300116e9d257e248d36 Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Wed, 13 Apr 2022 12:12:25 +0100 Subject: [PATCH 281/447] fix source of tar --- connectors/vmware/ci/scripts/vmware-deb-package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh index ca7d08ec7..41440beb4 100755 --- a/connectors/vmware/ci/scripts/vmware-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deb-package.sh @@ -18,7 +18,7 @@ mkdir -p /build cd /build cp -rv /src/centreon-vmware /build/ mv -v /build/centreon-vmware /build/centreon-plugin-virtualization-vmware-daemon -(cd /src && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz +(cd /build && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz cp -rv /src/centreon-vmware/ci/debian /build/centreon-plugin-virtualization-vmware-daemon/ ls -lart From ef1eec0e5042723c4b585726d30dd80babda8acf Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 14 Apr 2022 09:05:00 +0200 Subject: [PATCH 282/447] enh(discovery) add custom attributes --- .../src/centreon/vmware/cmddiscovery.pm | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 19ce44e64..50200bdb4 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -77,6 +77,14 @@ sub run { my @disco_data; my $disco_stats; + my $customFields = {}; + my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->customFieldsManager); + if (defined($entries->{field})) { + foreach (@{$entries->{field}}) { + $customFields->{ $_->{key} } = $_->{name}; + } + } + $disco_stats->{start_time} = time(); my $filters = $self->build_filter(label => 'name', search_option => 'datacenter', is_regexp => 'filter'); @@ -115,7 +123,8 @@ sub run { my @properties = ( 'name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', - 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState' + 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState', + 'summary.customValue' ); my $esxs = centreon::vmware::common::get_views($self->{connector}, \@{$cluster->host}, \@properties); @@ -124,6 +133,12 @@ sub run { foreach my $esx (@$esxs) { my %esx; + my $customValuesEsx = []; + if (defined($esx->{'summary.customValue'})) { + foreach (@{$esx->{'summary.customValue'}}) { + push @$customValuesEsx, { key => $customFields->{ $_->{key}}, value => $_->{value}}; + } + } $esx{type} = 'esx'; $esx{name} = $esx->name; $esx{os} = $esx->{'config.product.productLineId'} . ' ' . $esx->{'config.product.version'}; @@ -133,6 +148,7 @@ sub run { $esx{maintenance} = $esx->{'runtime.inMaintenanceMode'}; $esx{datacenter} = $datacenter->name; $esx{cluster} = $cluster->name; + $esx{custom_attributes} = $customValuesEsx; foreach my $nic (@{$esx->{'config.virtualNicManagerInfo.netConfig'}}) { my %lookup = map { $_->{'key'} => $_->{'spec'}->{'ip'}->{'ipAddress'} } @{$nic->{'candidateVnic'}}; @@ -147,7 +163,8 @@ sub run { @properties = ( 'parent', 'config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', - 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState' + 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState', + 'summary.customValue' ); my $vms = centreon::vmware::common::get_views($self->{connector}, \@{$esx->vm}, \@properties); @@ -158,6 +175,12 @@ sub run { next if (!defined($vm->{'config.uuid'}) || $vm->{'config.uuid'} eq ''); my $entry; + my $customValuesVm = []; + if (defined($vm->{'summary.customValue'})) { + foreach (@{$vm->{'summary.customValue'}}) { + push @$customValuesVm, { key => $customFields->{ $_->{key}}, value => $_->{value}}; + } + } $entry->{type} = 'vm'; $entry->{name} = $vm->{'config.name'}; $entry->{uuid} = $vm->{'config.uuid'}; @@ -172,6 +195,7 @@ sub run { $entry->{power_state} = $vm->{'runtime.powerState'}->val; $entry->{datacenter} = $datacenter->name; $entry->{cluster} = $cluster->name; + $entry->{custom_attributes} = $customValuesVm; $entry->{esx} = $esx->name; push @disco_data, $entry; From fe788ba890f8c8b2305b4772163aa246acbd4f43 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 14 Apr 2022 09:05:54 +0200 Subject: [PATCH 283/447] enh(discovery) add custom attributes --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 50200bdb4..101556f23 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -136,7 +136,7 @@ sub run { my $customValuesEsx = []; if (defined($esx->{'summary.customValue'})) { foreach (@{$esx->{'summary.customValue'}}) { - push @$customValuesEsx, { key => $customFields->{ $_->{key}}, value => $_->{value}}; + push @$customValuesEsx, { key => $customFields->{ $_->{key} }, value => $_->{value} }; } } $esx{type} = 'esx'; @@ -178,7 +178,7 @@ sub run { my $customValuesVm = []; if (defined($vm->{'summary.customValue'})) { foreach (@{$vm->{'summary.customValue'}}) { - push @$customValuesVm, { key => $customFields->{ $_->{key}}, value => $_->{value}}; + push @$customValuesVm, { key => $customFields->{ $_->{key} }, value => $_->{value} }; } } $entry->{type} = 'vm'; From 435999bd74d75a43c0392d263491153cd1849381 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 14 Apr 2022 09:08:54 +0200 Subject: [PATCH 284/447] prepare release 3.2.3 --- connectors/vmware/changelog | 3 +++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 40d5c56eb..9b283ab56 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2022-04-14 Quentin Garnier - 3.2.3 + * Enhancement: add custom attributes in discovery + 2021-12-21 Quentin Garnier - 3.2.2 * Enhancement: add 'storage-host' * Enhancement: add 'cpu-cluster' (issue #90) diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 15a1599c5..179343359 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.2.2'; +my $VERSION = '3.2.3'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 8462aa3ca..5e91dc431 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.2.2'; + $manager_response->{vmware_connector_version} = '3.2.3'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 2e9b1d4156a45eae01f4205f28db005a0c7d239e Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:11:03 +0200 Subject: [PATCH 285/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 5fca635cf..013178469 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -26,24 +26,15 @@ try { stash name: "rpms-centos7", includes: 'output/noarch/*.rpm' sh 'rm -rf output' } - }, - 'centos8': { - node { - sh 'setup_centreon_build.sh' - sh './centreon-build/jobs/vmware/vmware-package.sh centos8' - archiveArtifacts artifacts: 'rpms-centos8.tar.gz' - stash name: "rpms-centos8", includes: 'output/noarch/*.rpm' - sh 'rm -rf output' - } - }, + } 'Debian bullseye packaging and signing': { node { dir('centreon-vmware') { checkout scm } sh 'docker run -i --entrypoint "/src/centreon-vmware/ci/scripts/vmware-deb-package.sh" -w "/src" -v "$PWD:/src" -e "DISTRIB=Debian11" -e "VERSION=$VERSION" -e "RELEASE=$RELEASE" registry.centreon.com/centreon-debian11-dependencies:22.04' - stash name: 'Debian11', includes: 'Debian11/*.deb' - archiveArtifacts artifacts: "Debian11/*" + stash name: 'Debian11', includes: '*.deb' + archiveArtifacts artifacts: "*" } } if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { From e4244d4366cbe6ca1b402fd2bff5fc45c8d67f7a Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:14:30 +0200 Subject: [PATCH 286/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 013178469..6b2b243d9 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -26,7 +26,7 @@ try { stash name: "rpms-centos7", includes: 'output/noarch/*.rpm' sh 'rm -rf output' } - } + }, 'Debian bullseye packaging and signing': { node { dir('centreon-vmware') { From 7ee8e3a557aefc8eaccf2e2e9ff6a498b2963885 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:19:17 +0200 Subject: [PATCH 287/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 6b2b243d9..0fe9b8752 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -27,6 +27,15 @@ try { sh 'rm -rf output' } }, + 'alma8': { + node { + sh 'setup_centreon_build.sh' + sh './centreon-build/jobs/vmware/vmware-package.sh alma8' + archiveArtifacts artifacts: 'rpms-alma8.tar.gz' + stash name: "rpms-alma8", includes: 'output/noarch/*.rpm' + sh 'rm -rf output' + } + }, 'Debian bullseye packaging and signing': { node { dir('centreon-vmware') { @@ -45,7 +54,7 @@ try { node { sh 'setup_centreon_build.sh' unstash "rpms-centos7" - unstash "rpms-centos8" + unstash "rpms-alma8" sh './centreon-build/jobs/vmware/vmware-delivery.sh' } } From 6729faf10198592815f5a2fa5e40257b0726c324 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:30:14 +0200 Subject: [PATCH 288/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 0fe9b8752..21f54c327 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -53,6 +53,7 @@ try { stage('Delivery') { node { sh 'setup_centreon_build.sh' + unstash "Debian11" unstash "rpms-centos7" unstash "rpms-alma8" sh './centreon-build/jobs/vmware/vmware-delivery.sh' From d57c3775b2fdd20a3699760c238d797c0e1fcb9e Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:37:21 +0200 Subject: [PATCH 289/447] Create vmware-deliver-deb-package.sh --- .../vmware/ci/scripts/vmware-deliver-deb-package.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh new file mode 100644 index 000000000..9970c330b --- /dev/null +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +VERSION="$1" +BULLSEYEPACKAGES=`echo *.deb` + +for i in $BULLSEYEPACKAGES +do + echo "Sending $i\n" + curl -u \"$NEXUS_USERNAME:$NEXUS_PASSWORD\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/$VERSION" +done From c345d4274957a47add26d2c32abf7954e7e9a98c Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:38:06 +0200 Subject: [PATCH 290/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 21f54c327..8181ccd5c 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -57,6 +57,7 @@ try { unstash "rpms-centos7" unstash "rpms-alma8" sh './centreon-build/jobs/vmware/vmware-delivery.sh' + sh './ci/scripts/vmware-deliver-deb-package.sh' } } } catch(e) { From 8806b05d5fc068eb7fb343f280ca289d7a0db0fe Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:43:38 +0200 Subject: [PATCH 291/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 8181ccd5c..8d407d72a 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -57,7 +57,9 @@ try { unstash "rpms-centos7" unstash "rpms-alma8" sh './centreon-build/jobs/vmware/vmware-delivery.sh' - sh './ci/scripts/vmware-deliver-deb-package.sh' + withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { + sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' + } } } } catch(e) { From c4578c7dd5891458479f3a8e9203ceaefe6c8244 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 10:44:09 +0200 Subject: [PATCH 292/447] Update vmware-deliver-deb-package.sh --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index 9970c330b..eeec9eab8 100644 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -1,10 +1,10 @@ #!/bin/bash -VERSION="$1" +VERSION="$3" BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i\n" - curl -u \"$NEXUS_USERNAME:$NEXUS_PASSWORD\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/$VERSION" + curl -u \"$1:$2\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/$VERSION" done From 6eb3e4a35230f28c31e86b42c2eb94b968e54fa3 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:16:42 +0200 Subject: [PATCH 293/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 8d407d72a..14f8029c2 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -58,6 +58,9 @@ try { unstash "rpms-alma8" sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { + dir('centreon-vmware') { + checkout scm + } sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' } } From ed34b6c07cf94452ca1d086c74c8e43b9ac9c756 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:16:51 +0200 Subject: [PATCH 294/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 14f8029c2..aa538a4c3 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -56,7 +56,7 @@ try { unstash "Debian11" unstash "rpms-centos7" unstash "rpms-alma8" - sh './centreon-build/jobs/vmware/vmware-delivery.sh' + //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { dir('centreon-vmware') { checkout scm From 5c0d236cb0efdeb3a146753ff3bb57e9dddc62b6 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:23:33 +0200 Subject: [PATCH 295/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index aa538a4c3..02454329d 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -58,10 +58,8 @@ try { unstash "rpms-alma8" //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { - dir('centreon-vmware') { - checkout scm - } - sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' + checkout scm + sh './centreon-vmware/ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' } } } From 8946dc6ad6df8ba9059b3988226eed440e693f33 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:31:25 +0200 Subject: [PATCH 296/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 02454329d..7cfb5ad7e 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,6 +59,7 @@ try { //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm + ls -lart sh './centreon-vmware/ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' } } From 42e835b820a0d0481d1b66bc520f17bf069d6981 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:34:53 +0200 Subject: [PATCH 297/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 7cfb5ad7e..0bacb0a0b 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,7 +59,7 @@ try { //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm - ls -lart + sh 'ls -lart' sh './centreon-vmware/ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' } } From b17919b563cbbed766c9b8c223f4eafa2a3c9b44 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune <83596451+zguennoune02@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:36:19 +0200 Subject: [PATCH 298/447] Update Jenkinsfile --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 0bacb0a0b..a907d66e8 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -60,7 +60,7 @@ try { withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm sh 'ls -lart' - sh './centreon-vmware/ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' + sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' } } } From cbfaf87d6714fa12d53b7c47ed54502147771780 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 11:38:38 +0200 Subject: [PATCH 299/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh old mode 100644 new mode 100755 From 811a9f36ad13bbf2892f34b5e0e659df1d023564 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 11:48:05 +0200 Subject: [PATCH 300/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index eeec9eab8..8ef304c41 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -1,10 +1,11 @@ #!/bin/bash +set -ex VERSION="$3" BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do - echo "Sending $i\n" + echo "Sending $i" curl -u \"$1:$2\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/$VERSION" done From f3935cb697fbe51fe4c06edc7bd11b93fccbee88 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 11:53:40 +0200 Subject: [PATCH 301/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index 8ef304c41..d77be3f16 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -7,5 +7,5 @@ BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i" - curl -u \"$1:$2\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/$VERSION" + curl -u \"$1:$2\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" done From b813067adfc4d2b2c3b785c92a0a8b4d28f0b7b7 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:06:56 +0200 Subject: [PATCH 302/447] fix perm --- connectors/vmware/Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index a907d66e8..16069fb36 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,8 +59,7 @@ try { //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm - sh 'ls -lart' - sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD $VERSION' + sh './ci/scripts/vmware-deliver-deb-package.sh "$NEXUS_USERNAME" "$NEXUS_PASSWORD" "$VERSION"' } } } From fa8650f15bc7a586749dad74ee54ec4e453c06ac Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:10:42 +0200 Subject: [PATCH 303/447] fix perm --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 16069fb36..b67468316 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,7 +59,7 @@ try { //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm - sh './ci/scripts/vmware-deliver-deb-package.sh "$NEXUS_USERNAME" "$NEXUS_PASSWORD" "$VERSION"' + sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD' } } } From 43fe86d47ba7ca648192e57fa505b730ed410066 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:11:59 +0200 Subject: [PATCH 304/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index d77be3f16..9535fd7ac 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -7,5 +7,5 @@ BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i" - curl -u \"$1:$2\" -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" + curl -u \$1:$2\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" done From 33527119bc02b792c5913fdcdec8b945ae309947 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:13:10 +0200 Subject: [PATCH 305/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index 9535fd7ac..af505ab79 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -7,5 +7,5 @@ BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i" - curl -u \$1:$2\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" + curl -u \'$1':'$2'\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" done From 78c5eb9a59ea3b37a4d03152ff8d3012ac19088f Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:14:56 +0200 Subject: [PATCH 306/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index af505ab79..ce2c0d8ad 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -7,5 +7,5 @@ BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i" - curl -u \'$1':'$2'\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" + curl -u \`$1`:`$2`\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" done From 897eea6000de2d445604cd7b7590d3952ff287aa Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:17:25 +0200 Subject: [PATCH 307/447] fix perm --- connectors/vmware/Jenkinsfile | 2 +- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index b67468316..eb863b142 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,7 +59,7 @@ try { //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm - sh './ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD' + sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" } } } diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index ce2c0d8ad..7dcb4552c 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -1,11 +1,10 @@ #!/bin/bash set -ex -VERSION="$3" BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i" - curl -u \`$1`:`$2`\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" + curl -u \"$1:$2"\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" done From ded8963fdd5bcf9504aa1bed9f347883e7174d96 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:20:44 +0200 Subject: [PATCH 308/447] fix perm --- connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh index 7dcb4552c..2017d59cd 100755 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh @@ -6,5 +6,5 @@ BULLSEYEPACKAGES=`echo *.deb` for i in $BULLSEYEPACKAGES do echo "Sending $i" - curl -u \"$1:$2"\ -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" + curl -u \'$1:$2\' -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" done From cbb5c59dda83f6c515831ec36e894569d2cdb5cc Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:27:08 +0200 Subject: [PATCH 309/447] fix perm --- connectors/vmware/Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index eb863b142..a3bf8218e 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,7 +59,8 @@ try { //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm - sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" + //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" + sh 'curl -u \$NEXUS_USERNAME:$NEXUS_PASSWORD\ -H "Content-Type: multipart/form-data" --data-binary \"@/*.deb\" "https://apt.centreon.com/repository/22.04"' } } } From 0c3c0fed4395debb5465bf616eb52a07aca0c52c Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:28:11 +0200 Subject: [PATCH 310/447] fix perm --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index a3bf8218e..7be2bce0c 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -60,7 +60,7 @@ try { withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" - sh 'curl -u \$NEXUS_USERNAME:$NEXUS_PASSWORD\ -H "Content-Type: multipart/form-data" --data-binary \"@/*.deb\" "https://apt.centreon.com/repository/22.04"' + sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary @/*.deb https://apt.centreon.com/repository/22.04' } } } From a0257f321a923098be1b06731e258b80eaa0c46a Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:31:32 +0200 Subject: [PATCH 311/447] fix perm --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 7be2bce0c..aee8e3798 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -60,7 +60,7 @@ try { withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" - sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary @/*.deb https://apt.centreon.com/repository/22.04' + sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@/*.deb" https://apt.centreon.com/repository/22.04/' } } } From 1524be7bf60ce5cbeb1327834e5dac0ebff1ad42 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:50:32 +0200 Subject: [PATCH 312/447] test --- connectors/vmware/Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index aee8e3798..412e2c5c4 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -60,7 +60,8 @@ try { withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" - sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@/*.deb" https://apt.centreon.com/repository/22.04/' + sh 'BULLSEYEPACKAGES=`echo *.deb`' + sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$BULLSEYEPACKAGES" https://apt.centreon.com/repository/22.04/' } } } From e617a7c59dc37ac07dd353e66cf8e6a8efe39c40 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:55:56 +0200 Subject: [PATCH 313/447] test --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 412e2c5c4..4c1930197 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -60,7 +60,7 @@ try { withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" - sh 'BULLSEYEPACKAGES=`echo *.deb`' + sh 'BULLSEYEPACKAGES=`echo ../*.deb`' sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$BULLSEYEPACKAGES" https://apt.centreon.com/repository/22.04/' } } From 141b03ce0f7583286b4e3ca19684e773487e7b9b Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 12:58:51 +0200 Subject: [PATCH 314/447] test --- connectors/vmware/Jenkinsfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 4c1930197..248df3cab 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -53,15 +53,14 @@ try { stage('Delivery') { node { sh 'setup_centreon_build.sh' - unstash "Debian11" unstash "rpms-centos7" unstash "rpms-alma8" //sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm + unstash "Debian11" //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" - sh 'BULLSEYEPACKAGES=`echo ../*.deb`' - sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$BULLSEYEPACKAGES" https://apt.centreon.com/repository/22.04/' + sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./*.deb" https://apt.centreon.com/repository/22.04/' } } } From 87cb3f847e87241c5a6ce6e2f2a942117d9b4b96 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 13:05:07 +0200 Subject: [PATCH 315/447] test --- connectors/vmware/Jenkinsfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 248df3cab..14f7648b9 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -59,8 +59,13 @@ try { withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm unstash "Debian11" + sh 'ls -lart' //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" - sh 'curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./*.deb" https://apt.centreon.com/repository/22.04/' + sh '''for i in $(echo *.deb) + do + curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$i" https://apt.centreon.com/repository/22.04/ + done + ''' } } } From 3be026b0dc59df994a92cf12f93e5f6747c0c0c6 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 13:07:19 +0200 Subject: [PATCH 316/447] test --- connectors/vmware/Jenkinsfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 14f7648b9..161c7c7ff 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -55,12 +55,10 @@ try { sh 'setup_centreon_build.sh' unstash "rpms-centos7" unstash "rpms-alma8" - //sh './centreon-build/jobs/vmware/vmware-delivery.sh' + sh './centreon-build/jobs/vmware/vmware-delivery.sh' withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { checkout scm unstash "Debian11" - sh 'ls -lart' - //sh "./ci/scripts/vmware-deliver-deb-package.sh $NEXUS_USERNAME $NEXUS_PASSWORD" sh '''for i in $(echo *.deb) do curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$i" https://apt.centreon.com/repository/22.04/ From 44a95ebb2d6889a04ac54dbf8fafd2c894097186 Mon Sep 17 00:00:00 2001 From: Zakaria Guennoune Date: Thu, 14 Apr 2022 13:08:22 +0200 Subject: [PATCH 317/447] test --- connectors/vmware/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 161c7c7ff..c10b06388 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -61,7 +61,7 @@ try { unstash "Debian11" sh '''for i in $(echo *.deb) do - curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$i" https://apt.centreon.com/repository/22.04/ + curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$i" https://apt.centreon.com/repository/22.04-unstable/ done ''' } From fffbbfc1b09e58191086845a9a8ec1b72fb83784 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 20 Apr 2022 09:50:47 +0200 Subject: [PATCH 318/447] fix(discovery): custom attributes retrieved for vcenter only --- .../src/centreon/vmware/cmddiscovery.pm | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 101556f23..16f5ee4da 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -78,10 +78,14 @@ sub run { my $disco_stats; my $customFields = {}; - my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->customFieldsManager); - if (defined($entries->{field})) { - foreach (@{$entries->{field}}) { - $customFields->{ $_->{key} } = $_->{name}; + + my $api_type = $self->{connector}->{session1}->get_service_content()->about->apiType; + if ($api_type eq 'VirtualCenter') { + my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->customFieldsManager); + if (defined($entries->{field})) { + foreach (@{$entries->{field}}) { + $customFields->{ $_->{key} } = $_->{name}; + } } } @@ -123,9 +127,11 @@ sub run { my @properties = ( 'name', 'vm', 'config.virtualNicManagerInfo.netConfig', 'config.product.version', 'config.product.productLineId', 'hardware.systemInfo.vendor', 'hardware.systemInfo.model', - 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState', - 'summary.customValue' + 'hardware.systemInfo.uuid', 'runtime.powerState', 'runtime.inMaintenanceMode', 'runtime.connectionState' ); + if ($api_type eq 'VirtualCenter') { + push @properties, 'summary.customValue'; + } my $esxs = centreon::vmware::common::get_views($self->{connector}, \@{$cluster->host}, \@properties); next if (!defined($esxs)); @@ -163,9 +169,11 @@ sub run { @properties = ( 'parent', 'config.name', 'config.annotation', 'config.template', 'config.uuid', 'config.version', - 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState', - 'summary.customValue' + 'config.guestId', 'guest.guestState', 'guest.hostName', 'guest.ipAddress', 'runtime.powerState' ); + if ($api_type eq 'VirtualCenter') { + push @properties, 'summary.customValue'; + } my $vms = centreon::vmware::common::get_views($self->{connector}, \@{$esx->vm}, \@properties); next if (!defined($vms)); From 618a89b02dac17bcb54e8a497f5f5803be96c306 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 26 Apr 2022 13:18:44 +0200 Subject: [PATCH 319/447] prepare release 3.2.4 --- connectors/vmware/changelog | 3 +++ connectors/vmware/src/centreon/script/centreon_vmware.pm | 2 +- connectors/vmware/src/centreon/vmware/common.pm | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 9b283ab56..96850651c 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2022-04-14 Quentin Garnier - 3.2.4 + * Fix: custom attributes retrieved for vcenter only + 2022-04-14 Quentin Garnier - 3.2.3 * Enhancement: add custom attributes in discovery diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 179343359..962a80d2c 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -54,7 +54,7 @@ BEGIN { use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.2.3'; +my $VERSION = '3.2.4'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 5e91dc431..014258e18 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.2.3'; + $manager_response->{vmware_connector_version} = '3.2.4'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); From 7bafb52475cf7651b7a2b422648268d4fa9fc722 Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Tue, 17 May 2022 11:38:16 +0100 Subject: [PATCH 320/447] Normalize VERSION variable to Debian format --- connectors/vmware/Jenkinsfile | 2 +- connectors/vmware/ci/scripts/vmware-deb-package.sh | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index c10b06388..98a4a2cdb 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -41,7 +41,7 @@ try { dir('centreon-vmware') { checkout scm } - sh 'docker run -i --entrypoint "/src/centreon-vmware/ci/scripts/vmware-deb-package.sh" -w "/src" -v "$PWD:/src" -e "DISTRIB=Debian11" -e "VERSION=$VERSION" -e "RELEASE=$RELEASE" registry.centreon.com/centreon-debian11-dependencies:22.04' + sh 'docker run -i --entrypoint "/src/centreon-vmware/ci/scripts/vmware-deb-package.sh" -w "/src" -v "$PWD:/src" -e "DISTRIB=bullseye" -e "VERSION=$VERSION" -e "RELEASE=$RELEASE" registry.centreon.com/centreon-debian11-dependencies:22.04' stash name: 'Debian11', includes: '*.deb' archiveArtifacts artifacts: "*" } diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh index 41440beb4..19d03d96e 100755 --- a/connectors/vmware/ci/scripts/vmware-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deb-package.sh @@ -16,6 +16,10 @@ if [ -d /build ]; then fi mkdir -p /build cd /build + +# fix version to debian format accept +VERSION="$(echo $VERSION | sed 's/-/./g')" + cp -rv /src/centreon-vmware /build/ mv -v /build/centreon-vmware /build/centreon-plugin-virtualization-vmware-daemon (cd /build && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz @@ -23,7 +27,7 @@ cp -rv /src/centreon-vmware/ci/debian /build/centreon-plugin-virtualization-vmwa ls -lart cd /build/centreon-plugin-virtualization-vmware-daemon -debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "$VERSION" -y -r "$RELEASE" +debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "$VERSION" -y -r "$DISTRIB" debuild-pbuilder cd /build From a1e58ad37b91dee39f87269c16969b3be8917f8f Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Sun, 19 Jun 2022 12:45:45 +0100 Subject: [PATCH 321/447] Add build of perl-vmware-vsphere dependency --- connectors/vmware/ci/debian/control | 3 ++- connectors/vmware/ci/scripts/vmware-deb-package.sh | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control index f14c0aad7..dd39fb8a5 100644 --- a/connectors/vmware/ci/debian/control +++ b/connectors/vmware/ci/debian/control @@ -14,5 +14,6 @@ Depends: ${misc:Depends}, libjson-xs-perl, liblwp-protocol-https-perl, libzmq-constants-perl, - zmq-libzmq4-perl + zmq-libzmq4-perl, + perl-vmware-vsphere Description: Perl daemon to monitor VSphere Infrastructure diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh index 19d03d96e..eb1c8756f 100755 --- a/connectors/vmware/ci/scripts/vmware-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deb-package.sh @@ -20,12 +20,21 @@ cd /build # fix version to debian format accept VERSION="$(echo $VERSION | sed 's/-/./g')" +# Make perl-VMware-vSphere dependecy +wget -O - https://gitlab.labexposed.com/centreon-lab/perl-VMware-vSphere/-/raw/master/storage/VMware-vSphere-Perl-SDK-7.0.0-17698549.x86_64.tar.gz | tar zxvf - +mv vmware-vsphere-cli-distrib vmware-vsphere-cli +tar czvf vmware-vsphere-cli-7.0.0.tar.gz vmware-vsphere-cli +cd vmware-vsphere-cli +git clone https://github.com/centreon-lab/perl-vmware-debian debian +debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "7.0.0" -y -r "${DISTRIB}" +debuild-pbuilder +cd .. + cp -rv /src/centreon-vmware /build/ mv -v /build/centreon-vmware /build/centreon-plugin-virtualization-vmware-daemon (cd /build && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz cp -rv /src/centreon-vmware/ci/debian /build/centreon-plugin-virtualization-vmware-daemon/ -ls -lart cd /build/centreon-plugin-virtualization-vmware-daemon debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "$VERSION" -y -r "$DISTRIB" debuild-pbuilder @@ -36,4 +45,5 @@ if [ -d "$DISTRIB" ] ; then fi mkdir $DISTRIB mv /build/*.deb $DISTRIB/ +ls -lart /build/$DISTRIB mv /build/$DISTRIB/*.deb /src From f0c4e040e97acb11ff6252080d725ad3380e6149 Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Mon, 11 Jul 2022 12:41:25 +0100 Subject: [PATCH 322/447] add missing dependency --- connectors/vmware/ci/debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control index dd39fb8a5..77e256c42 100644 --- a/connectors/vmware/ci/debian/control +++ b/connectors/vmware/ci/debian/control @@ -14,6 +14,7 @@ Depends: ${misc:Depends}, libjson-xs-perl, liblwp-protocol-https-perl, libzmq-constants-perl, + libtext-template-perl, zmq-libzmq4-perl, perl-vmware-vsphere Description: Perl daemon to monitor VSphere Infrastructure From c112455712c5d91bd1ec413b7d3bd34f080bc696 Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Wed, 27 Jul 2022 15:37:58 +0100 Subject: [PATCH 323/447] MON-14383 fix install files and config --- ...ugin-virtualization-vmware-daemon.postinst | 10 --------- .../vmware/ci/debian/contrib/centreon_vmware | 1 - .../ci/debian/contrib/centreon_vmware.pm | 1 - ...lization-vmware-daemon.install => install} | 4 ++-- connectors/vmware/ci/debian/postinst | 22 +++++++++++++++++++ 5 files changed, 24 insertions(+), 14 deletions(-) delete mode 100644 connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst delete mode 120000 connectors/vmware/ci/debian/contrib/centreon_vmware delete mode 120000 connectors/vmware/ci/debian/contrib/centreon_vmware.pm rename connectors/vmware/ci/debian/{centreon-plugin-virtualization-vmware-daemon.install => install} (50%) create mode 100644 connectors/vmware/ci/debian/postinst diff --git a/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst b/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst deleted file mode 100644 index 93e80a677..000000000 --- a/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.postinst +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -if [ "$1" = "configure" ] ; then - - systemctl daemon-reload - systemctl enable centreon_vmware.service - systemctl restart centreon_vmware.service - -fi -exit 0 \ No newline at end of file diff --git a/connectors/vmware/ci/debian/contrib/centreon_vmware b/connectors/vmware/ci/debian/contrib/centreon_vmware deleted file mode 120000 index d2806142a..000000000 --- a/connectors/vmware/ci/debian/contrib/centreon_vmware +++ /dev/null @@ -1 +0,0 @@ -../../../contrib/debian/centreon_vmware-systemd \ No newline at end of file diff --git a/connectors/vmware/ci/debian/contrib/centreon_vmware.pm b/connectors/vmware/ci/debian/contrib/centreon_vmware.pm deleted file mode 120000 index 2f0885ece..000000000 --- a/connectors/vmware/ci/debian/contrib/centreon_vmware.pm +++ /dev/null @@ -1 +0,0 @@ -../../../contrib/config/centreon_vmware-conf.pm \ No newline at end of file diff --git a/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.install b/connectors/vmware/ci/debian/install similarity index 50% rename from connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.install rename to connectors/vmware/ci/debian/install index 62e8bab0b..d1b8c1853 100644 --- a/connectors/vmware/ci/debian/centreon-plugin-virtualization-vmware-daemon.install +++ b/connectors/vmware/ci/debian/install @@ -1,4 +1,4 @@ centreon_vmware.pl usr/bin -debian/contrib/centreon_vmware lib/systemd/system -debian/contrib/centreon_vmware.pm etc/centreon +contrib/debian/centreon_vmware-systemd lib/systemd/system +contrib/config/centreon_vmware-conf.pm etc/centreon centreon/* usr/share/perl5/centreon diff --git a/connectors/vmware/ci/debian/postinst b/connectors/vmware/ci/debian/postinst new file mode 100644 index 000000000..1080a2ed7 --- /dev/null +++ b/connectors/vmware/ci/debian/postinst @@ -0,0 +1,22 @@ +#!/bin/sh + +if [ "$1" = "configure" ] ; then + + if [ -e "/lib/systemd/system/centreon_vmware-systemd" ]; then + mv /lib/systemd/system/centreon_vmware-systemd /lib/systemd/system/centreon_vmware.service + fi + + if [ -e "/etc/centreon/centreon_vmware-conf.pm" ]; then + mv /etc/centreon/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm + fi + + if [ "$(getent passwd centreon)" ]; then + chown centreon:centreon /etc/centreon/centreon_vmware.pm + fi + + systemctl daemon-reload + systemctl enable centreon_vmware.service + systemctl restart centreon_vmware.service + +fi +exit 0 \ No newline at end of file From 31f4bc3d2b079eb6b9c80ace47b44de096039948 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 28 Jul 2022 15:56:46 +0200 Subject: [PATCH 324/447] add tags to discovery --- .../vmware/src/centreon/class/cisTags.pm | 268 ++++++++++ .../src/centreon/class/http/backend/curl.pm | 471 ++++++++++++++++++ .../class/http/backend/curlconstants.pm | 33 ++ .../src/centreon/class/http/backend/lwp.pm | 251 ++++++++++ .../centreon/class/http/backend/useragent.pm | 50 ++ .../vmware/src/centreon/class/http/http.pm | 257 ++++++++++ .../src/centreon/script/centreon_vmware.pm | 46 +- .../vmware/src/centreon/vmware/cmdbase.pm | 9 +- .../src/centreon/vmware/cmddiscovery.pm | 33 +- .../vmware/src/centreon/vmware/cmdlicenses.pm | 2 +- .../vmware/src/centreon/vmware/common.pm | 43 +- .../vmware/src/centreon/vmware/connector.pm | 40 +- 12 files changed, 1443 insertions(+), 60 deletions(-) create mode 100644 connectors/vmware/src/centreon/class/cisTags.pm create mode 100644 connectors/vmware/src/centreon/class/http/backend/curl.pm create mode 100644 connectors/vmware/src/centreon/class/http/backend/curlconstants.pm create mode 100644 connectors/vmware/src/centreon/class/http/backend/lwp.pm create mode 100644 connectors/vmware/src/centreon/class/http/backend/useragent.pm create mode 100644 connectors/vmware/src/centreon/class/http/http.pm diff --git a/connectors/vmware/src/centreon/class/cisTags.pm b/connectors/vmware/src/centreon/class/cisTags.pm new file mode 100644 index 000000000..f66130c6b --- /dev/null +++ b/connectors/vmware/src/centreon/class/cisTags.pm @@ -0,0 +1,268 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::class::cisTags; + +use strict; +use warnings; +use centreon::class::http::http; +use JSON::XS; + +# https://developer.vmware.com/apis/vsphere-automation/v7.0U2/cis/ + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{is_error} = 1; + $self->{error} = 'configuration missing'; + $self->{is_logged} = 0; + + return $self; +} + +sub json_decode { + my ($self, %options) = @_; + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($options{content}); + }; + if ($@) { + $self->{is_error} = 1; + $self->{error} = "cannot decode json response: $@"; + return undef; + } + + return $decoded; +} + +sub error { + my ($self, %options) = @_; + + return $self->{error}; +} + +sub configuration { + my ($self, %options) = @_; + + foreach (('url', 'username', 'password')) { + if (!defined($options{$_}) || + $options{$_} eq '') { + $self->{error} = $_ . ' configuration missing'; + return 1; + } + + $self->{$_} = $options{$_}; + } + + if ($self->{url} =~ /^((?:http|https):\/\/.*?)\//) { + $self->{url} = $1; + } + + $self->{http_backend} = defined($options{backend}) ? $options{backend} : 'curl'; + + $self->{curl_opts} = ['CURLOPT_SSL_VERIFYPEER => 0', 'CURLOPT_POSTREDIR => CURL_REDIR_POST_ALL']; + my $curl_opts = []; + if (defined($options{curlopts})) { + foreach (keys %{$options{curlopts}}) { + push @{$curl_opts}, $_ . ' => ' . $options{curlopts}->{$_}; + } + } + if (scalar(@$curl_opts) > 0) { + $self->{curl_opts} = $curl_opts; + } + + $self->{http} = centreon::class::http::http->new(logger => $options{logger}); + $self->{is_error} = 0; + return 0; +} + +sub authenticate { + my ($self, %options) = @_; + + my ($code, $content) = $self->{http}->request( + http_backend => $self->{http_backend}, + method => 'POST', + query_form_post => '', + hostname => '', + full_url => $self->{url} . '/rest/com/vmware/cis/session', + header => [ + 'Accept-Type: application/json; charset=utf-8', + 'Content-Type: application/json; charset=utf-8', + ], + curl_opt => $self->{curl_opts}, + credentials => 1, + basic => 1, + username => $self->{username}, + password => $self->{password}, + warning_status => '', + unknown_status => '', + critical_status => '' + ); + if ($code) { + $self->{is_error} = 1; + $self->{error} = 'http request error'; + return undef; + } + if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { + $self->{is_error} = 1; + $self->{error} = "Login error [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"; + return undef; + } + + my $decoded = $self->json_decode(content => $content); + return if (!defined($decoded)); + + my $token = defined($decoded->{value}) ? $decoded->{value} : undef; + if (!defined($token)) { + $self->{is_error} = 1; + $self->{error} = 'authenticate issue - cannot get token'; + return undef; + } + + $self->{token} = $token; + $self->{is_logged} = 1; +} + +sub request { + my ($self, %options) = @_; + + if (!defined($self->{url})) { + $self->{is_error} = 1; + $self->{error} = 'configuration missing'; + return 1; + } + + $self->{is_error} = 0; + if ($self->{is_logged} == 0) { + $self->authenticate(); + } + + return 1 if ($self->{is_logged} == 0); + + my ($code, $content) = $self->{http}->request( + http_backend => $self->{http_backend}, + method => $options{method}, + hostname => '', + full_url => $self->{url} . $options{endpoint}, + query_form_post => $options{query_form_post}, + get_param => $options{get_param}, + header => [ + 'Accept-Type: application/json; charset=utf-8', + 'Content-Type: application/json; charset=utf-8', + 'vmware-api-session-id: ' . $self->{token} + ], + curl_opt => $self->{curl_opts}, + warning_status => '', + unknown_status => '', + critical_status => '' + ); + + my $decoded = $self->json_decode(content => $content); + + # code 403 means forbidden (token not good maybe) + if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { + $self->{token} = undef; + $self->{is_logged} = 0; + $self->{is_error} = 1; + $self->{error} = $content; + $self->{error} = $decoded->{value}->[0]->{default_message} if (defined($decoded) && defined($decoded->{value}->[0]->{default_message})); + return 1; + } + + return 1 if (!defined($decoded)); + + return (0, $decoded); +} + +sub tagsByResource { + my ($self, %options) = @_; + + my ($code, $tag_ids) = $self->request( + method => 'GET', + endpoint => '/rest/com/vmware/cis/tagging/tag' + ); + return $code if ($code); + + my $tags = {}; + my $result = { esx => {} , vm => {} }; + if (defined($tag_ids->{value})) { + my $json_req = { tag_ids => [] }; + foreach my $tag_id (@{$tag_ids->{value}}) { + my ($code, $tag_detail) = $self->request( + method => 'GET', + endpoint => '/rest/com/vmware/cis/tagging/tag/id:' . $tag_id + ); + return $code if ($code); + + push @{$json_req->{tag_ids}}, $tag_id; + $tags->{ $tag_id } = { name => $tag_detail->{value}->{name}, description => $tag_detail->{value}->{description} }; + } + + my $data; + eval { + $data = encode_json($json_req); + }; + if ($@) { + $self->{is_error} = 1; + $self->{error} = "cannot encode json request: $@"; + return undef; + } + + my ($code, $tags_assoc) = $self->request( + method => 'POST', + endpoint => '/rest/com/vmware/cis/tagging/tag-association', + get_param => ['~action=list-attached-objects-on-tags'], + query_form_post => $data + ); + return $code if ($code); + + if (defined($tags_assoc->{value})) { + foreach my $entry (@{$tags_assoc->{value}}) { + foreach my $entity (@{$entry->{object_ids}}) { + if ($entity->{type} eq 'VirtualMachine') { + $result->{vm}->{ $entity->{id} } = [] if (!defined($result->{vm}->{ $entity->{id} })); + push @{$result->{vm}->{ $entity->{id} }}, $tags->{ $entry->{tag_id} }; + } elsif ($entity->{type} eq 'HostSystem') { + $result->{esx}->{ $entity->{id} } = [] if (!defined($result->{esx}->{ $entity->{id} })); + push @{$result->{esx}->{ $entity->{id} }}, $tags->{ $entry->{tag_id} }; + } + } + } + } + } + + return (0, $result); +} + +sub DESTROY { + my ($self) = @_; + + if ($self->{is_logged} == 1) { + $self->request( + method => 'DELETE', + endpoint => '/rest/com/vmware/cis/session' + ); + } +} + +1; diff --git a/connectors/vmware/src/centreon/class/http/backend/curl.pm b/connectors/vmware/src/centreon/class/http/backend/curl.pm new file mode 100644 index 000000000..9c95d29b2 --- /dev/null +++ b/connectors/vmware/src/centreon/class/http/backend/curl.pm @@ -0,0 +1,471 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::class::http::backend::curl; + +use strict; +use warnings; +use URI; +use Net::Curl::Easy; +use centreon::class::http::backend::curlconstants; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{logger} = $options{logger}; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + $self->{constant_cb} = \¢reon::class::http::backend::curlconstants::get_constant_value; + + if (!defined($options{request}->{curl_opt})) { + $options{request}->{curl_opt} = []; + } +} + +my $http_code_explained = { + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => '(Unused)', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 450 => 'Timeout reached', # custom code + 451 => 'Failed Connection Host', # custom code + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported' +}; + +sub cb_debug { + my ($easy, $type, $data, $uservar) = @_; + + chomp $data; + $data =~ s/\r//mg; + + my $msg = ''; + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_TEXT')) { + $msg = sprintf("== Info: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_HEADER_OUT')) { + $msg = sprintf("=> Send header: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_DATA_OUT')) { + $msg = sprintf("=> Send data: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_SSL_DATA_OUT')) { + #$msg = sprintf("=> Send SSL data: %s", $data); + return 0; + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_HEADER_IN')) { + $msg = sprintf("=> Recv header: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_DATA_IN')) { + $msg = sprintf("=> Recv data: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_SSL_DATA_IN')) { + #$msg = sprintf("=> Recv SSL data: %s", $data); + return 0; + } + + $uservar->{logger}->writeLogDebug($msg); + return 0; +} + +sub curl_setopt { + my ($self, %options) = @_; + + eval { + $self->{curl_easy}->setopt($options{option}, $options{parameter}); + }; + if ($@) { + $self->{logger}->writeLogError("curl setopt error: '" . $@ . "'."); + } +} + +sub set_method { + my ($self, %options) = @_; + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CUSTOMREQUEST'), parameter => undef); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POSTFIELDS'), parameter => undef); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPGET'), parameter => 1); + + if ($options{request}->{method} eq 'GET') { + return ; + } + + if ($options{content_type_forced} == 1) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POSTFIELDS'), parameter => $options{request}->{query_form_post}) + if (defined($options{request}->{query_form_post})); + } elsif (defined($options{request}->{post_params})) { + my $uri_post = URI->new(); + $uri_post->query_form($options{request}->{post_params}); + push @{$options{headers}}, 'Content-Type: application/x-www-form-urlencoded'; + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POSTFIELDS'), parameter => $uri_post->query); + } + + if ($options{request}->{method} eq 'POST') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POST'), parameter => 1); + } + if ($options{request}->{method} eq 'PUT') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CUSTOMREQUEST'), parameter => $options{request}->{method}); + } + if ($options{request}->{method} eq 'DELETE') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CUSTOMREQUEST'), parameter => $options{request}->{method}); + } +} + +sub set_auth { + my ($self, %options) = @_; + + if (defined($options{request}->{credentials})) { + if (defined($options{request}->{basic})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_BASIC')); + } elsif (defined($options{request}->{ntlmv2})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_NTLM')); + } else { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_ANY')); + } + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_USERPWD'), parameter => $options{request}->{username} . ':' . $options{request}->{password}); + } + + if (defined($options{request}->{cert_file}) && $options{request}->{cert_file} ne '') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLCERT'), parameter => $options{request}->{cert_file}); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLKEY'), parameter => $options{request}->{key_file}); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_KEYPASSWD'), parameter => $options{request}->{cert_pwd}); + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLCERTTYPE'), parameter => "PEM"); + if (defined($options{request}->{cert_pkcs12})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLCERTTYPE'), parameter => "P12"); + } +} + +sub set_proxy { + my ($self, %options) = @_; + + if (defined($options{request}->{proxyurl}) && $options{request}->{proxyurl} ne '') { + if ($options{request}->{proxyurl} =~ /^(?:http|https):\/\/(.*?):(.*?)@/) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_PROXYUSERNAME'), parameter => $1); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_PROXYPASSWORD'), parameter => $2); + $options{request}->{proxyurl} =~ s/\/\/$1:$2@//; + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_PROXY'), parameter => $options{request}->{proxyurl}); + } + + if (defined($options{request}->{proxypac}) && $options{request}->{proxypac} ne '') { + $self->{logger}->writeLogError('Unsupported proxypac option'); + } +} + +sub trim { + my ($self, $value) = @_; + + # Sometimes there is a null character + $value =~ s/\x00$//; + $value =~ s/^[ \t\n]+//; + $value =~ s/[ \t\n]+$//; + return $value; +} + +sub set_extra_curl_opt { + my ($self, %options) = @_; + + my $entries = {}; + foreach (@{$options{request}->{curl_opt}}) { + my ($key, $value) = split /=>/; + $key = $self->trim($key); + + if (!defined($entries->{$key})) { + $entries->{$key} = { val => [], force_array => 0 }; + } + + $value = $self->trim($value); + if ($value =~ /^\[(.*)\]$/) { + $entries->{$key}->{force_array} = 1; + $value = $self->trim($1); + } + if ($value =~ /^CURLOPT|CURL/) { + $value = $self->{constant_cb}->(name => $value); + } + + push @{$entries->{$key}->{val}}, $value; + } + + foreach (keys %$entries) { + my $key = $_; + if (/^CURLOPT|CURL/) { + $key = $self->{constant_cb}->(name => $_); + } + + if ($entries->{$_}->{force_array} == 1 || scalar(@{$entries->{$_}->{val}}) > 1) { + $self->curl_setopt(option => $key, parameter => $entries->{$_}->{val}); + } else { + $self->curl_setopt(option => $key, parameter => pop @{$entries->{$_}->{val}}); + } + } +} + + +sub cb_get_header { + my ($easy, $header, $uservar) = @_; + + $header =~ s/[\r\n]//g; + if ($header =~ /^[\r\n]*$/) { + $uservar->{nheaders}++; + } else { + $uservar->{response_headers}->[$uservar->{nheaders}] = {} + if (!defined($uservar->{response_headers}->[$uservar->{nheaders}])); + if ($header =~ /^(\S(?:.*?))\s*:\s*(.*)/) { + my $header_name = lc($1); + $uservar->{response_headers}->[$uservar->{nheaders}]->{$header_name} = [] + if (!defined($uservar->{response_headers}->[$uservar->{nheaders}]->{$header_name})); + push @{$uservar->{response_headers}->[$uservar->{nheaders}]->{$header_name}}, $2; + } else { + $uservar->{response_headers}->[$uservar->{nheaders}]->{response_line} = $header; + } + } + + return length($_[1]); +} + +sub request { + my ($self, %options) = @_; + + if (!defined($self->{curl_easy})) { + $self->{curl_easy} = Net::Curl::Easy->new(); + } + + if ($self->{logger}->is_debug()) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_DEBUGFUNCTION'), parameter => \&cb_debug); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_DEBUGDATA'), parameter => $self); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_VERBOSE'), parameter => 1); + } + + if (defined($options{request}->{timeout})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_TIMEOUT'), parameter => $options{request}->{timeout}); + } + if (defined($options{request}->{cookies_file})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_COOKIEFILE'), parameter => $options{request}->{cookies_file}); + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_FOLLOWLOCATION'), parameter => 1); + if (defined($options{request}->{no_follow})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_FOLLOWLOCATION'), parameter => 0); + } + + my $url; + if (defined($options{request}->{full_url})) { + $url = $options{request}->{full_url}; + } elsif (defined($options{request}->{port}) && $options{request}->{port} =~ /^[0-9]+$/) { + $url = $options{request}->{proto}. "://" . $options{request}->{hostname} . ':' . $options{request}->{port} . $options{request}->{url_path}; + } else { + $url = $options{request}->{proto}. "://" . $options{request}->{hostname} . $options{request}->{url_path}; + } + + if (defined($options{request}->{http_peer_addr}) && $options{request}->{http_peer_addr} ne '') { + $url =~ /^(?:http|https):\/\/(.*?)(\/|\:|$)/; + $self->{curl_easy}->setopt( + $self->{constant_cb}->(name => 'CURLOPT_RESOLVE'), + [$1 . ':' . $options{request}->{port_force} . ':' . $options{request}->{http_peer_addr}] + ); + } + + my $uri = URI->new($url); + if (defined($options{request}->{get_params})) { + $uri->query_form($options{request}->{get_params}); + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_URL'), parameter => $uri); + + my $headers = []; + my $content_type_forced = 0; + foreach my $key (keys %{$options{request}->{headers}}) { + push @$headers, $key . ':' . $options{request}->{headers}->{$key}; + if ($key =~ /content-type/i) { + $content_type_forced = 1; + } + } + + $self->set_method(%options, content_type_forced => $content_type_forced, headers => $headers); + + if (scalar(@$headers) > 0) { + $self->{curl_easy}->setopt($self->{constant_cb}->(name => 'CURLOPT_HTTPHEADER'), $headers); + } + + if (defined($options{request}->{cacert_file}) && $options{request}->{cacert_file} ne '') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CAINFO'), parameter => $options{request}->{cacert_file}); + } + + $self->set_auth(%options); + $self->set_proxy(%options); + $self->set_extra_curl_opt(%options); + + $self->{response_body} = ''; + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_FILE'), parameter => \$self->{response_body}); + $self->{nheaders} = 0; + $self->{response_headers} = [{}]; + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HEADERDATA'), parameter => $self); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HEADERFUNCTION'), parameter => \&cb_get_header); + + eval { + $SIG{__DIE__} = sub {}; + + $self->{curl_easy}->perform(); + }; + if ($@) { + my $err = $@; + if (ref($@) eq "Net::Curl::Easy::Code") { + my $num = $@; + if ($num == $self->{constant_cb}->(name => 'CURLE_OPERATION_TIMEDOUT')) { + $self->{response_code} = 450; + } elsif ($num == $self->{constant_cb}->(name => 'CURLE_COULDNT_CONNECT')) { + $self->{response_code} = 451; + } + } + + if (!defined($self->{response_code})) { + $self->{logger}->writeLogError('curl perform error : ' . $err); + } + + return 1; + } + + $self->{response_code} = $self->{curl_easy}->getinfo($self->{constant_cb}->(name => 'CURLINFO_RESPONSE_CODE')); + + return (0, $self->{response_body}); +} + +sub get_headers { + my ($self, %options) = @_; + + my $headers = ''; + foreach (keys %{$self->{response_headers}->[$options{nheader}]}) { + next if (/response_line/); + foreach my $value (@{$self->{response_headers}->[$options{nheader}]->{$_}}) { + $headers .= "$_: " . $value . "\n"; + } + } + + return $headers; +} + +sub get_first_header { + my ($self, %options) = @_; + + if (!defined($options{name})) { + return $self->get_headers(nheader => 0); + } + + return undef + if (!defined($self->{response_headers}->[0]->{ lc($options{name}) })); + return wantarray ? @{$self->{response_headers}->[0]->{ lc($options{name}) }} : $self->{response_headers}->[0]->{ lc($options{name}) }->[0]; +} + +sub get_header { + my ($self, %options) = @_; + + if (!defined($options{name})) { + return $self->get_headers(nheader => -1); + } + + return undef + if (!defined($self->{response_headers}->[-1]->{ lc($options{name}) })); + return wantarray ? @{$self->{response_headers}->[-1]->{ lc($options{name}) }} : $self->{response_headers}->[-1]->{ lc($options{name}) }->[0]; +} + +sub get_code { + my ($self, %options) = @_; + + return $self->{response_code}; +} + +sub get_message { + my ($self, %options) = @_; + + return $http_code_explained->{$self->{response_code}}; +} + +1; + +__END__ + +=head1 NAME + +HTTP Curl backend layer. + +=head1 SYNOPSIS + +HTTP Curl backend layer. + +=head1 BACKEND CURL OPTIONS + +=over 8 + +=item B<--curl-opt> + +Set CURL Options (--curl-opt="CURLOPT_SSL_VERIFYPEER => 0" --curl-opt="CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_1" ). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/connectors/vmware/src/centreon/class/http/backend/curlconstants.pm b/connectors/vmware/src/centreon/class/http/backend/curlconstants.pm new file mode 100644 index 000000000..1f78aa86d --- /dev/null +++ b/connectors/vmware/src/centreon/class/http/backend/curlconstants.pm @@ -0,0 +1,33 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::class::http::backend::curlconstants; + +use strict; +use warnings; +use Net::Curl::Easy qw(:constants); + +sub get_constant_value { + my (%options) = @_; + + return eval $options{name}; +} + +1; diff --git a/connectors/vmware/src/centreon/class/http/backend/lwp.pm b/connectors/vmware/src/centreon/class/http/backend/lwp.pm new file mode 100644 index 000000000..de490efa2 --- /dev/null +++ b/connectors/vmware/src/centreon/class/http/backend/lwp.pm @@ -0,0 +1,251 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::class::http::backend::lwp; + +use strict; +use warnings; +use centreon::class::http::backend::useragent; +use URI; +use IO::Socket::SSL; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{logger} = $options{logger}; + $self->{ua} = undef; + $self->{debug_handlers} = 0; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + $self->{ssl_context} = ''; + if (!defined($options{request}->{ssl_opt})) { + $options{request}->{ssl_opt} = []; + } + if (defined($options{request}->{ssl}) && $options{request}->{ssl} ne '') { + push @{$options{request}->{ssl_opt}}, 'SSL_version => ' . $options{request}->{ssl}; + } + if (defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pkcs12})) { + push @{$options{request}->{ssl_opt}}, 'SSL_use_cert => 1'; + push @{$options{request}->{ssl_opt}}, 'SSL_cert_file => "' . $options{request}->{cert_file} . '"'; + push @{$options{request}->{ssl_opt}}, 'SSL_key_file => "' . $options{request}->{key_file} . '"' + if (defined($options{request}->{key_file})); + push @{$options{request}->{ssl_opt}}, 'SSL_ca_file => "' . $options{request}->{cacert_file} . '"' + if (defined($options{request}->{cacert_file})); + } + my $append = ''; + foreach (@{$options{request}->{ssl_opt}}) { + if ($_ ne '') { + $self->{ssl_context} .= $append . $_; + $append = ', '; + } + } +} + +sub set_proxy { + my ($self, %options) = @_; + + if (defined($options{request}->{proxyurl}) && $options{request}->{proxyurl} ne '') { + $self->{ua}->proxy(['http', 'https'], $options{request}->{proxyurl}); + } +} + +sub request { + my ($self, %options) = @_; + + my $request_options = $options{request}; + if (!defined($self->{ua})) { + $self->{ua} = centreon::plugins::backend::http::useragent->new( + keep_alive => 1, protocols_allowed => ['http', 'https'], timeout => $request_options->{timeout}, + credentials => $request_options->{credentials}, username => $request_options->{username}, password => $request_options->{password}); + } + + if ($self->{logger}->is_debug() && $self->{debug_handlers} == 0) { + $self->{debug_handlers} = 1; + $self->{ua}->add_handler("request_send", sub { + my ($response, $ua, $handler) = @_; + + $self->{logger}->writeLogDebug("======> request send"); + $self->{logger}->writeLogDebug($response->as_string); + return ; + }); + $self->{ua}->add_handler("response_done", sub { + my ($response, $ua, $handler) = @_; + + $self->{logger}->writeLogDebug("======> response done"); + $self->{logger}->writeLogDebug($response->as_string); + return ; + }); + } + + if (defined($request_options->{no_follow})) { + $self->{ua}->requests_redirectable(undef); + } else { + $self->{ua}->requests_redirectable([ 'GET', 'HEAD', 'POST' ]); + } + if (defined($request_options->{http_peer_addr})) { + push @LWP::Protocol::http::EXTRA_SOCK_OPTS, PeerAddr => $request_options->{http_peer_addr}; + } + + my ($req, $url); + if (defined($request_options->{full_url})) { + $url = $request_options->{full_url}; + } elsif (defined($request_options->{port}) && $request_options->{port} =~ /^[0-9]+$/) { + $url = $request_options->{proto}. "://" . $request_options->{hostname} . ':' . $request_options->{port} . $request_options->{url_path}; + } else { + $url = $request_options->{proto}. "://" . $request_options->{hostname} . $request_options->{url_path}; + } + + my $uri = URI->new($url); + if (defined($request_options->{get_params})) { + $uri->query_form($request_options->{get_params}); + } + $req = HTTP::Request->new($request_options->{method}, $uri); + + my $content_type_forced; + foreach my $key (keys %{$request_options->{headers}}) { + if ($key !~ /content-type/i) { + $req->header($key => $request_options->{headers}->{$key}); + } else { + $content_type_forced = $request_options->{headers}->{$key}; + } + } + + if ($request_options->{method} eq 'POST') { + if (defined($content_type_forced)) { + $req->content_type($content_type_forced); + $req->content($request_options->{query_form_post}); + } else { + my $uri_post = URI->new(); + if (defined($request_options->{post_params})) { + $uri_post->query_form($request_options->{post_params}); + } + $req->content_type('application/x-www-form-urlencoded'); + $req->content($uri_post->query); + } + } + + if (defined($request_options->{credentials}) && defined($request_options->{basic})) { + $req->authorization_basic($request_options->{username}, $request_options->{password}); + } + + $self->set_proxy(request => $request_options, url => $url); + + if (defined($request_options->{cert_pkcs12}) && $request_options->{cert_file} ne '' && $request_options->{cert_pwd} ne '') { + eval "use Net::SSL"; die $@ if $@; + $ENV{HTTPS_PKCS12_FILE} = $request_options->{cert_file}; + $ENV{HTTPS_PKCS12_PASSWORD} = $request_options->{cert_pwd}; + } + + if (defined($self->{ssl_context}) && $self->{ssl_context} ne '') { + my $context = new IO::Socket::SSL::SSL_Context(eval $self->{ssl_context}); + IO::Socket::SSL::set_default_context($context); + } + + $self->{response} = $self->{ua}->request($req); + + $self->{headers} = $self->{response}->headers(); + return (0, $self->{response}->content); +} + +sub get_headers { + my ($self, %options) = @_; + + my $headers = ''; + foreach ($options{response}->header_field_names()) { + $headers .= "$_: " . $options{response}->header($_) . "\n"; + } + + return $headers; +} + +sub get_first_header { + my ($self, %options) = @_; + + my @redirects = $self->{response}->redirects(); + if (!defined($options{name})) { + return $self->get_headers(response => defined($redirects[0]) ? $redirects[0] : $self->{response}); + } + + return + defined($redirects[0]) ? + $redirects[0]->headers()->header($options{name}) : + $self->{headers}->header($options{name}) + ; +} + +sub get_header { + my ($self, %options) = @_; + + if (!defined($options{name})) { + return $self->get_headers(response => $self->{response}); + } + return $self->{headers}->header($options{name}); +} + +sub get_code { + my ($self, %options) = @_; + + return $self->{response}->code(); +} + +sub get_message { + my ($self, %options) = @_; + + return $self->{response}->message(); +} + +1; + +__END__ + +=head1 NAME + +HTTP LWP backend layer. + +=head1 SYNOPSIS + +HTTP LWP backend layer. + +=head1 BACKEND LWP OPTIONS + +=over 8 + +=item B<--ssl-opt> + +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). + +=item B<--ssl> + +Set SSL version (--ssl=TLSv1). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/connectors/vmware/src/centreon/class/http/backend/useragent.pm b/connectors/vmware/src/centreon/class/http/backend/useragent.pm new file mode 100644 index 000000000..2a9a1c2c2 --- /dev/null +++ b/connectors/vmware/src/centreon/class/http/backend/useragent.pm @@ -0,0 +1,50 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::class::http::backend::useragent; + +use strict; +use warnings; +use base 'LWP::UserAgent'; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self = LWP::UserAgent::new(@_); + $self->agent('centreon::class::http::backend::useragent'); + + $self->{credentials} = $options{credentials} if defined($options{credentials}); + $self->{username} = $options{username} if defined($options{username}); + $self->{password} = $options{password} if defined($options{password}); + + return $self; +} + +sub get_basic_credentials { + my($self, $realm, $uri, $proxy) = @_; + return if $proxy; + return $self->{username}, $self->{password} if $self->{credentials} and wantarray; + return $self->{username}.":".$self->{password} if $self->{credentials}; + return undef; +} + +1; diff --git a/connectors/vmware/src/centreon/class/http/http.pm b/connectors/vmware/src/centreon/class/http/http.pm new file mode 100644 index 000000000..cd75c315e --- /dev/null +++ b/connectors/vmware/src/centreon/class/http/http.pm @@ -0,0 +1,257 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::class::http::http; + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{logger} = $options{logger}; + $self->{options} = { + proto => 'http', + url_path => '/', + timeout => 5, + method => 'GET', + }; + + $self->{add_headers} = {}; + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{options} = { %{$self->{options}} }; + foreach (keys %options) { + $self->{options}->{$_} = $options{$_} if (defined($options{$_})); + } +} + +sub add_header { + my ($self, %options) = @_; + + $self->{add_headers}->{$options{key}} = $options{value}; +} + +sub mymodule_load { + my ($self, %options) = @_; + my $file; + ($file = ($options{module} =~ /\.pm$/ ? $options{module} : $options{module} . '.pm')) =~ s{::}{/}g; + + eval { + local $SIG{__DIE__} = 'IGNORE'; + require $file; + $file =~ s{/}{::}g; + $file =~ s/\.pm$//; + }; + if ($@) { + $self->{logger}->writeLogError('[core] ' . $options{error_msg} . ' - ' . $@); + return 1; + } + return wantarray ? (0, $file) : 0; +} + +sub check_options { + my ($self, %options) = @_; + + $options{request}->{http_backend} = 'curl' + if (!defined($options{request}->{http_backend}) || $options{request}->{http_backend} eq ''); + $self->{http_backend} = $options{request}->{http_backend}; + if ($self->{http_backend} !~ /^\s*lwp|curl\s*$/i) { + $self->{logger}->writeLogError("Unsupported http backend specified '" . $self->{http_backend} . "'."); + return 1; + } + + if (!defined($self->{backend_lwp}) && !defined($self->{backend_curl})) { + if ($options{request}->{http_backend} eq 'lwp' && $self->mymodule_load( + logger => $options{logger}, module => 'centreon::class::http::backend::lwp', + error_msg => "Cannot load module 'centreon::class::http::backend::lwp'." + ) == 0) { + $self->{backend_lwp} = centreon::class::http::backend::lwp->new(%options, logger => $self->{logger}); + } + + if ($options{request}->{http_backend} eq 'curl' && $self->mymodule_load( + logger => $options{logger}, module => 'centreon::class::http::backend::curl', + error_msg => "Cannot load module 'centreon::class::http::backend::curl'." + ) == 0) { + $self->{backend_curl} = centreon::class::http::backend::curl->new(%options, logger => $self->{logger}); + } + } + + if (($options{request}->{proto} ne 'http') && ($options{request}->{proto} ne 'https')) { + $self->{logger}->writeLogError("Unsupported protocol specified '" . $self->{option_results}->{proto} . "'."); + return 1; + } + if (!defined($options{request}->{hostname})) { + $self->{logger}->writeLogError("Please set the hostname option"); + return 1; + } + if ((defined($options{request}->{credentials})) && (!defined($options{request}->{username}) || !defined($options{request}->{password}))) { + $self->{logger}->writeLogError("You need to set --username= and --password= options when --credentials is used"); + return 1; + } + if ((defined($options{request}->{cert_pkcs12})) && (!defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pwd}))) { + $self->{logger}->writeLogError("You need to set --cert-file= and --cert-pwd= options when --pkcs12 is used"); + return 1; + } + + $options{request}->{port_force} = $self->get_port(); + + $options{request}->{headers} = {}; + if (defined($options{request}->{header})) { + foreach (@{$options{request}->{header}}) { + if (/^(.*?):(.*)/) { + $options{request}->{headers}->{$1} = $2; + } + } + } + foreach (keys %{$self->{add_headers}}) { + $options{request}->{headers}->{$_} = $self->{add_headers}->{$_}; + } + + foreach my $method (('get', 'post')) { + if (defined($options{request}->{$method . '_param'})) { + $options{request}->{$method . '_params'} = {}; + foreach (@{$options{request}->{$method . '_param'}}) { + if (/^([^=]+)={0,1}(.*)$/) { + my $key = $1; + my $value = defined($2) ? $2 : 1; + if (defined($options{request}->{$method . '_params'}->{$key})) { + if (ref($options{request}->{$method . '_params'}->{$key}) ne 'ARRAY') { + $options{request}->{$method . '_params'}->{$key} = [ $options{request}->{$method . '_params'}->{$key} ]; + } + push @{$options{request}->{$method . '_params'}->{$key}}, $value; + } else { + $options{request}->{$method . '_params'}->{$key} = $value; + } + } + } + } + } + + $self->{ 'backend_' . $self->{http_backend} }->check_options(%options); + return 0; +} + +sub get_port { + my ($self, %options) = @_; + + my $port = ''; + if (defined($self->{options}->{port}) && $self->{options}->{port} ne '') { + $port = $self->{options}->{port}; + } else { + $port = 80 if ($self->{options}->{proto} eq 'http'); + $port = 443 if ($self->{options}->{proto} eq 'https'); + } + + return $port; +} + +sub get_port_request { + my ($self, %options) = @_; + + my $port = ''; + if (defined($self->{options}->{port}) && $self->{options}->{port} ne '') { + $port = $self->{options}->{port}; + } + return $port; +} + +sub request { + my ($self, %options) = @_; + + my $request_options = { %{$self->{options}} }; + foreach (keys %options) { + $request_options->{$_} = $options{$_} if (defined($options{$_})); + } + return 1 if ($self->check_options(request => $request_options)); + + return $self->{'backend_' . $self->{http_backend}}->request(request => $request_options); +} + +sub get_first_header { + my ($self, %options) = @_; + + return $self->{'backend_' . $self->{http_backend}}->get_first_header(%options); +} + +sub get_header { + my ($self, %options) = @_; + + return $self->{'backend_' . $self->{http_backend}}->get_header(%options); +} + +sub get_code { + my ($self, %options) = @_; + + return $self->{'backend_' . $self->{http_backend}}->get_code(); +} + +sub get_message { + my ($self, %options) = @_; + + return $self->{'backend_' . $self->{http_backend}}->get_message(); +} + +1; + +__END__ + +=head1 NAME + +HTTP abstraction layer. + +=head1 SYNOPSIS + +HTTP abstraction layer for lwp and curl backends + +=head1 HTTP GLOBAL OPTIONS + +=over 8 + +=item B<--http-peer-addr> + +Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) + +=item B<--proxyurl> + +Proxy URL + +=item B<--proxypac> + +Proxy pac file (can be an url or local file) + +=item B<--http-backend> + +Set the backend used (Default: 'lwp') +For curl: --http-backend=curl + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/connectors/vmware/src/centreon/script/centreon_vmware.pm b/connectors/vmware/src/centreon/script/centreon_vmware.pm index 962a80d2c..a82c46432 100644 --- a/connectors/vmware/src/centreon/script/centreon_vmware.pm +++ b/connectors/vmware/src/centreon/script/centreon_vmware.pm @@ -47,14 +47,14 @@ BEGIN { # required for new IO::Socket::SSL versions require IO::Socket::SSL; IO::Socket::SSL->import(); - IO::Socket::SSL::set_ctx_defaults( SSL_verify_mode => 0 ); + IO::Socket::SSL::set_ctx_defaults( SSL_verify_mode => 0, SSL_no_shutdown => 1 ); }; } use base qw(centreon::vmware::script); use vars qw(%centreon_vmware_config); -my $VERSION = '3.2.4'; +my $VERSION = '3.2.5'; my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my @load_modules = ( @@ -99,7 +99,7 @@ my @load_modules = ( 'centreon::vmware::cmdtoolsvm', 'centreon::vmware::cmduptimehost', 'centreon::vmware::cmdvmoperationcluster', - 'centreon::vmware::cmdvsanclusterusage', + 'centreon::vmware::cmdvsanclusterusage' ); sub new { @@ -108,7 +108,7 @@ sub new { bless $self, $class; $self->add_options( - 'config-extra=s' => \$self->{opt_extra}, + 'config-extra=s' => \$self->{opt_extra} ); %{$self->{centreon_vmware_default_config}} = @@ -132,7 +132,7 @@ sub new { # 'username' => 'XXXXX', # 'password' => 'XXXXXX'} }, - vsan_sdk_path => '/usr/local/share/perl5/VMware', + vsan_sdk_path => '/usr/local/share/perl5/VMware' ); $self->{return_child} = {}; @@ -141,7 +141,7 @@ sub new { $self->{counter_stats} = {}; $self->{whoaim} = undef; # to know which vsphere to connect $self->{modules_registry} = {}; - + return $self; } @@ -151,7 +151,7 @@ sub init { # redefine to avoid out when we try modules $SIG{__DIE__} = undef; - + if (!defined($self->{opt_extra})) { $self->{opt_extra} = "/etc/centreon/centreon_vmware.pm"; } @@ -244,7 +244,7 @@ sub handle_TERM { my $self = shift; $self->{logger}->writeLogInfo("$$ Receiving order to stop..."); $self->{stop} = 1; - + foreach (keys %{$self->{childs_vpshere_pid}}) { kill('TERM', $_); $self->{logger}->writeLogInfo("Send -TERM signal to '" . $self->{childs_vpshere_pid}->{$_} . "' process.."); @@ -264,7 +264,7 @@ sub handle_CHLD { while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { $self->{return_child}{$child_pid} = {status => 1, rtime => time()}; } - + $SIG{CHLD} = \&class_handle_CHLD; } @@ -275,17 +275,17 @@ sub load_module { (my $file = "$_.pm") =~ s{::}{/}g; require $file; my $obj = $_->new(logger => $self->{logger}, case_insensitive => $self->{centreon_vmware_config}->{case_insensitive}); - $self->{modules_registry}->{$obj->getCommandName()} = $obj; + $self->{modules_registry}->{ $obj->getCommandName() } = $obj; } } sub verify_child_vsphere { my $self = shift; - + # Some dead process. need to relaunch it foreach (keys %{$self->{return_child}}) { delete $self->{return_child}->{$_}; - + if (defined($self->{childs_vpshere_pid}->{$_})) { if ($self->{stop} == 0) { my $name = $self->{childs_vpshere_pid}->{$_}; @@ -327,23 +327,23 @@ sub waiting_ready { my ($self, %options) = @_; return 1 if ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 1); - + # Need to check if we need to relaunch (maybe it can have a problem) $self->check_childs(); - + my $time = time(); # We wait 10 seconds while ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 0 && time() - $time < 10) { zmq_poll($self->{poll}, 5000); } - + if ($self->{centreon_vmware_config}->{vsphere_server}->{$options{container}}->{ready} == 0) { centreon::vmware::common::set_response(code => -1, short_message => "connector still not ready."); centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return 0; } - + return 1; } @@ -356,7 +356,7 @@ sub request_dynamic { centreon::vmware::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } - + my $container = md5_hex($options{result}->{vsphere_address} . $options{result}->{vsphere_username} . $options{result}->{vsphere_password}); # Need to create fork if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$container})) { @@ -374,7 +374,7 @@ sub request_dynamic { ); $centreon_vmware->create_vsphere_child(vsphere_name => $container, dynamic => 1); } - + return if ($self->waiting_ready( container => $container, manager => $options{manager}, identity => $options{identity}) == 0); @@ -392,7 +392,7 @@ sub request_dynamic { sub request { my ($self, %options) = @_; - + # Decode json my $result; eval { @@ -450,7 +450,7 @@ sub request { sub repserver { my ($self, %options) = @_; - + # Decode json my $result; eval { @@ -549,7 +549,7 @@ sub create_vsphere_child { sub bind_ipc { my ($self, %options) = @_; - + if (zmq_bind($options{socket}, 'ipc://' . $options{ipc_file}) == -1) { $self->{logger}->writeLogError("Cannot bind ipc '$options{ipc_file}': $!"); # try create dir @@ -597,8 +597,8 @@ sub run { { socket => $frontend, events => ZMQ_POLLIN, - callback => \&router_event, - }, + callback => \&router_event + } ]; # Switch messages between sockets diff --git a/connectors/vmware/src/centreon/vmware/cmdbase.pm b/connectors/vmware/src/centreon/vmware/cmdbase.pm index 5aea8144e..0725e93f9 100644 --- a/connectors/vmware/src/centreon/vmware/cmdbase.pm +++ b/connectors/vmware/src/centreon/vmware/cmdbase.pm @@ -21,6 +21,8 @@ package centreon::vmware::cmdbase; use strict; use warnings; use centreon::vmware::common; +use VMware::VIRuntime; +use VMware::VILib; my %handlers = (ALRM => {}); @@ -30,7 +32,7 @@ sub new { bless $self, $class; $self->{logger} = $options{logger}; - $self->{global_case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; + $self->{global_case_insensitive} = defined($options{case_insensitive}) ? $options{case_insensitive} : 0; return $self; } @@ -74,6 +76,11 @@ sub set_connector { my ($self, %options) = @_; $self->{connector} = $options{connector}; + + #$self->{connector}->{session_clone} = Vim::load_session(service_url => $self->{connector}->{service_url}, session_file => '/tmp/plop.save'); + #$self->{connector}->{session_clone} = Vim->new(service_url => $self->{connector}->{service_url}); + #$self->{connector}->{session_clone}->load_session(session_file => '/tmp/plop.save'); + $self->set_signal_handlers(); alarm(300); } diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 16f5ee4da..1ae8eab8f 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -25,6 +25,7 @@ use base qw(centreon::vmware::cmdbase); use strict; use warnings; use centreon::vmware::common; +use centreon::class::cisTags; sub new { my ($class, %options) = @_; @@ -32,7 +33,7 @@ sub new { bless $self, $class; $self->{commandName} = 'discovery'; - + return $self; } @@ -44,6 +45,7 @@ sub checkArgs { return 1; } + $self->{tags} = $options{arguments}->{tags} if (defined($options{arguments}->{tags})); $self->{resource_type} = $options{arguments}->{resource_type} if (defined($options{arguments}->{resource_type})); return 0; @@ -73,20 +75,35 @@ sub get_folders { sub run { my $self = shift; - + my @disco_data; my $disco_stats; + my ($rv, $tags); my $customFields = {}; - my $api_type = $self->{connector}->{session1}->get_service_content()->about->apiType; + my $api_type = $self->{connector}->{session}->get_service_content()->about->apiType; if ($api_type eq 'VirtualCenter') { - my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->customFieldsManager); + my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session}->get_service_content()->customFieldsManager); if (defined($entries->{field})) { foreach (@{$entries->{field}}) { $customFields->{ $_->{key} } = $_->{name}; } } + + if (defined($self->{tags})) { + my $cisTags = centreon::class::cisTags->new(); + $cisTags->configuration( + url => $self->{connector}->{config_vsphere_url}, + username => $self->{connector}->{config_vsphere_user}, + password => $self->{connector}->{config_vsphere_pass}, + logger => $self->{connector}->{logger} + ); + ($rv, $tags) = $cisTags->tagsByResource(); + if ($rv) { + $self->{connector}->{logger}->writeLogError("cannot get tags: " . $cisTags->error()); + } + } } $disco_stats->{start_time} = time(); @@ -155,6 +172,10 @@ sub run { $esx{datacenter} = $datacenter->name; $esx{cluster} = $cluster->name; $esx{custom_attributes} = $customValuesEsx; + if (defined($tags)) { + $esx{tags} = []; + $esx{tags} = $tags->{esx}->{ $esx->{mo_ref}->{value} } if (defined($tags->{esx}->{ $esx->{mo_ref}->{value} })); + } foreach my $nic (@{$esx->{'config.virtualNicManagerInfo.netConfig'}}) { my %lookup = map { $_->{'key'} => $_->{'spec'}->{'ip'}->{'ipAddress'} } @{$nic->{'candidateVnic'}}; @@ -205,6 +226,10 @@ sub run { $entry->{cluster} = $cluster->name; $entry->{custom_attributes} = $customValuesVm; $entry->{esx} = $esx->name; + if (defined($tags)) { + $entry->{tags} = []; + $entry->{tags} = $tags->{vm}->{ $vm->{mo_ref}->{value} } if (defined($tags->{vm}->{ $vm->{mo_ref}->{value} })); + } push @disco_data, $entry; } diff --git a/connectors/vmware/src/centreon/vmware/cmdlicenses.pm b/connectors/vmware/src/centreon/vmware/cmdlicenses.pm index 5d0c7db14..2b90aa89c 100644 --- a/connectors/vmware/src/centreon/vmware/cmdlicenses.pm +++ b/connectors/vmware/src/centreon/vmware/cmdlicenses.pm @@ -43,7 +43,7 @@ sub checkArgs { sub run { my $self = shift; - my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session1}->get_service_content()->licenseManager); + my $entries = centreon::vmware::common::get_view($self->{connector}, $self->{connector}->{session}->get_service_content()->licenseManager); my $data = {}; if (defined($entries->licenses)) { diff --git a/connectors/vmware/src/centreon/vmware/common.pm b/connectors/vmware/src/centreon/vmware/common.pm index 014258e18..5c5080ad3 100644 --- a/connectors/vmware/src/centreon/vmware/common.pm +++ b/connectors/vmware/src/centreon/vmware/common.pm @@ -45,7 +45,7 @@ sub init_response { my (%options) = @_; $manager_response->{code} = 0; - $manager_response->{vmware_connector_version} = '3.2.4'; + $manager_response->{vmware_connector_version} = '3.2.5'; $manager_response->{short_message} = 'OK'; $manager_response->{extra_message} = ''; $manager_response->{identity} = $options{identity} if (defined($options{identity})); @@ -109,12 +109,16 @@ sub connect_vsphere { eval { $SIG{ALRM} = sub { die('TIMEOUT'); }; alarm($options{connect_timeout}); - $options{connector}->{session1} = Vim->new(service_url => $options{url}); - $options{connector}->{session1}->login( + $options{connector}->{session} = Vim->new(service_url => $options{url}); + $options{connector}->{session}->login( user_name => $options{username}, password => $options{password} ); + $options{connector}->{service_url} = $options{url}; + #$options{connector}->{session}->save_session(session_file => '/tmp/plop.save'); + #$options{connector}->{session}->unset_logout_on_disconnect(); + get_vsan_vim(%options) if ($options{vsan_enabled} == 1); alarm(0); @@ -125,13 +129,7 @@ sub connect_vsphere { $options{logger}->writeLogError("'$options{whoaim}' Login to VirtualCenter server failed: $@"); return 1; } -# eval { -# $session_id = Vim::get_session_id(); -# }; -# if($@) { -# writeLogFile("Can't get session_id: $@\n"); -# return 1; -# } + return 0; } @@ -140,14 +138,14 @@ sub heartbeat { my $stime; eval { - $stime = $options{connector}->{session1}->get_service_instance()->CurrentTime(); + $stime = $options{connector}->{session}->get_service_instance()->CurrentTime(); $options{connector}->{keeper_session_time} = time(); }; if ($@) { $options{connector}->{logger}->writeLogError("$@"); # Try a second time eval { - $stime = $options{connector}->{session1}->get_service_instance()->CurrentTime(); + $stime = $options{connector}->{session}->get_service_instance()->CurrentTime(); $options{connector}->{keeper_session_time} = time(); }; if ($@) { @@ -180,7 +178,7 @@ sub get_views { my $results; eval { - $results = $obj_vmware->{session1}->get_views(mo_ref_array => $_[0], properties => $_[1]); + $results = $obj_vmware->{session}->get_views(mo_ref_array => $_[0], properties => $_[1]); }; if ($@) { vmware_error($obj_vmware, $@); @@ -194,7 +192,7 @@ sub get_view { my $results; eval { - $results = $obj_vmware->{session1}->get_view(mo_ref => $_[0], properties => $_[1]); + $results = $obj_vmware->{session}->get_view(mo_ref => $_[0], properties => $_[1]); }; if ($@) { vmware_error($obj_vmware, $@); @@ -464,7 +462,7 @@ sub cache_perf_counters { my $obj_vmware = shift; eval { - $obj_vmware->{perfmanager_view} = $obj_vmware->{session1}->get_view(mo_ref => $obj_vmware->{session1}->get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']); + $obj_vmware->{perfmanager_view} = $obj_vmware->{session}->get_view(mo_ref => $obj_vmware->{session}->get_service_content()->perfManager, properties => ['perfCounter', 'historicalInterval']); foreach (@{$obj_vmware->{perfmanager_view}->perfCounter}) { my $label = $_->groupInfo->key . "." . $_->nameInfo->key . "." . $_->rollupType->val; $obj_vmware->{perfcounter_cache}->{$label} = { key => $_->key, unitkey => $_->unitInfo->key, level => $_->level }; @@ -491,6 +489,7 @@ sub cache_perf_counters { $obj_vmware->{logger}->writeLogError("'" . $obj_vmware->{whoaim} . "' $@"); return 1; } + return 0; } @@ -570,18 +569,18 @@ sub find_entity_views { eval { if (defined($options{begin_entity})) { - $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, begin_entity => $options{begin_entity}); + $entity_views = $options{connector}->{session}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, begin_entity => $options{begin_entity}); } else { - $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); + $entity_views = $options{connector}->{session}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); } }; if ($@) { $options{connector}->{logger}->writeLogError("'" . $options{connector}->{whoaim} . "' $@"); eval { if (defined($options{begin_entity})) { - $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, begin_entity => $options{begin_entity}); + $entity_views = $options{connector}->{session}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}, begin_entity => $options{begin_entity}); } else { - $entity_views = $options{connector}->{session1}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); + $entity_views = $options{connector}->{session}->find_entity_views(view_type => $options{view_type}, properties => $options{properties}, filter => $options{filter}); } }; if ($@) { @@ -716,9 +715,9 @@ sub get_vsan_vim { my (%options) = @_; require URI::URL; - my $session_id = $options{connector}->{session1}->get_session_id(); - my $url = URI::URL->new($options{connector}->{session1}->get_service_url()); - my $api_type = $options{connector}->{session1}->get_service_content()->about->apiType; + my $session_id = $options{connector}->{session}->get_session_id(); + my $url = URI::URL->new($options{connector}->{session}->get_service_url()); + my $api_type = $options{connector}->{session}->get_service_content()->about->apiType; my $service_url_path = "sdk/vimService"; my $path = "vsanHealth"; diff --git a/connectors/vmware/src/centreon/vmware/connector.pm b/connectors/vmware/src/centreon/vmware/connector.pm index e546ba4c6..abfab28a6 100644 --- a/connectors/vmware/src/centreon/vmware/connector.pm +++ b/connectors/vmware/src/centreon/vmware/connector.pm @@ -28,6 +28,22 @@ use File::Basename; use POSIX ":sys_wait_h"; use centreon::vmware::common; +BEGIN { + # In new version version of LWP (version 6), the backend is now 'IO::Socket::SSL' (instead Crypt::SSLeay) + # it's a hack if you unset that + #$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL"; + + # The option is not omit to verify the certificate chain. + $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; + + eval { + # required for new IO::Socket::SSL versions + require IO::Socket::SSL; + IO::Socket::SSL->import(); + IO::Socket::SSL::set_ctx_defaults(SSL_verify_mode => 0); + }; +} + my %handlers = (TERM => {}, HUP => {}, CHLD => {}); my ($connector, $backend); @@ -49,7 +65,7 @@ sub new { $connector->{perfcounter_refreshrate} = 20; $connector->{perfcounter_speriod} = -1; $connector->{stop} = 0; - $connector->{session1} = undef; + $connector->{session} = undef; $connector->{modules_registry} = $options{modules_registry}; $connector->{logger} = $options{logger}; @@ -138,8 +154,11 @@ sub verify_child { delete $self->{return_child}->{$self->{child_proc}->{$_}->{pid}}; delete $self->{child_proc}->{$_}; } elsif (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { - $self->response_router(code => -1, msg => 'Timeout process', - identity => $_); + $self->response_router( + code => -1, + msg => 'Timeout process', + identity => $_ + ); kill('INT', $self->{child_proc}->{$_}->{pid}); delete $self->{child_proc}->{$_}; } else { @@ -185,8 +204,11 @@ sub reqclient { exit(0); } } else { - $self->response_router(code => -1, msg => 'Container connection problem', - identity => $result->{identity}); + $self->response_router( + code => -1, + msg => 'Container connection problem', + identity => $result->{identity} + ); } } @@ -250,7 +272,7 @@ sub run { if ($connector->{stop} && !$progress) { if ($connector->{vsphere_connected}) { eval { - $connector->{session1}->logout(); + $connector->{session}->logout(); }; } @@ -267,9 +289,9 @@ sub run { $connector->{logger}->writeLogError("'" . $connector->{whoaim} . "' Disconnect"); $connector->{vsphere_connected} = 0; eval { - $connector->{session1}->logout(); + $connector->{session}->logout(); }; - delete $connector->{session1}; + delete $connector->{session}; } if ($connector->{vsphere_connected} == 0) { @@ -281,7 +303,7 @@ sub run { url => $connector->{config_vsphere_url}, username => $connector->{config_vsphere_user}, password => $connector->{config_vsphere_pass}, - vsan_enabled => $connector->{vsan_enabled}, + vsan_enabled => $connector->{vsan_enabled} ) ) { $connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' Vsphere connection ok"); From 8458e89adc0cf9168dfd45c9c30ccdc5d4a2d0e9 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 9 Aug 2022 11:15:00 +0200 Subject: [PATCH 325/447] prepare version 3.2.5 --- connectors/vmware/changelog | 3 +++ connectors/vmware/ci/debian/control | 1 + 2 files changed, 4 insertions(+) diff --git a/connectors/vmware/changelog b/connectors/vmware/changelog index 96850651c..0b146c7b0 100644 --- a/connectors/vmware/changelog +++ b/connectors/vmware/changelog @@ -1,3 +1,6 @@ +2022-08-09 Quentin Garnier - 3.2.5 + * Enhancement: add tags in discovery + 2022-04-14 Quentin Garnier - 3.2.4 * Fix: custom attributes retrieved for vcenter only diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control index 77e256c42..7cc486fa5 100644 --- a/connectors/vmware/ci/debian/control +++ b/connectors/vmware/ci/debian/control @@ -11,6 +11,7 @@ Architecture: all Depends: ${misc:Depends}, ${shlibs:Depends}, libio-socket-inet6-perl, + libnet-curl-perl, libjson-xs-perl, liblwp-protocol-https-perl, libzmq-constants-perl, From 7753ac37381871599a1eccbdff0f4f629e7e9e0e Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 10 Aug 2022 10:30:30 +0200 Subject: [PATCH 326/447] add empty tags array to discovery by default --- connectors/vmware/src/centreon/vmware/cmddiscovery.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index 1ae8eab8f..ec49b516c 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -172,8 +172,8 @@ sub run { $esx{datacenter} = $datacenter->name; $esx{cluster} = $cluster->name; $esx{custom_attributes} = $customValuesEsx; + $esx{tags} = []; if (defined($tags)) { - $esx{tags} = []; $esx{tags} = $tags->{esx}->{ $esx->{mo_ref}->{value} } if (defined($tags->{esx}->{ $esx->{mo_ref}->{value} })); } @@ -226,8 +226,8 @@ sub run { $entry->{cluster} = $cluster->name; $entry->{custom_attributes} = $customValuesVm; $entry->{esx} = $esx->name; + $entry->{tags} = []; if (defined($tags)) { - $entry->{tags} = []; $entry->{tags} = $tags->{vm}->{ $vm->{mo_ref}->{value} } if (defined($tags->{vm}->{ $vm->{mo_ref}->{value} })); } From 93bf6153af713d774f8ff868a3b48760ba19b849 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 16 Aug 2022 09:20:32 +0200 Subject: [PATCH 327/447] change tags path for packaging --- .../src/centreon/{class => vmware}/cisTags.pm | 6 +++--- .../vmware/src/centreon/vmware/cmddiscovery.pm | 4 ++-- .../{class => vmware}/http/backend/curl.pm | 6 +++--- .../http/backend/curlconstants.pm | 2 +- .../centreon/{class => vmware}/http/backend/lwp.pm | 4 ++-- .../{class => vmware}/http/backend/useragent.pm | 4 ++-- .../src/centreon/{class => vmware}/http/http.pm | 14 +++++++------- 7 files changed, 20 insertions(+), 20 deletions(-) rename connectors/vmware/src/centreon/{class => vmware}/cisTags.pm (98%) rename connectors/vmware/src/centreon/{class => vmware}/http/backend/curl.pm (98%) rename connectors/vmware/src/centreon/{class => vmware}/http/backend/curlconstants.pm (94%) rename connectors/vmware/src/centreon/{class => vmware}/http/backend/lwp.pm (98%) rename connectors/vmware/src/centreon/{class => vmware}/http/backend/useragent.pm (92%) rename connectors/vmware/src/centreon/{class => vmware}/http/http.pm (91%) diff --git a/connectors/vmware/src/centreon/class/cisTags.pm b/connectors/vmware/src/centreon/vmware/cisTags.pm similarity index 98% rename from connectors/vmware/src/centreon/class/cisTags.pm rename to connectors/vmware/src/centreon/vmware/cisTags.pm index f66130c6b..5d4656deb 100644 --- a/connectors/vmware/src/centreon/class/cisTags.pm +++ b/connectors/vmware/src/centreon/vmware/cisTags.pm @@ -18,11 +18,11 @@ # limitations under the License. # -package centreon::class::cisTags; +package centreon::vmware::cisTags; use strict; use warnings; -use centreon::class::http::http; +use centreon::vmware::http::http; use JSON::XS; # https://developer.vmware.com/apis/vsphere-automation/v7.0U2/cis/ @@ -91,7 +91,7 @@ sub configuration { $self->{curl_opts} = $curl_opts; } - $self->{http} = centreon::class::http::http->new(logger => $options{logger}); + $self->{http} = centreon::vmware::http::http->new(logger => $options{logger}); $self->{is_error} = 0; return 0; } diff --git a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm index ec49b516c..690641f66 100644 --- a/connectors/vmware/src/centreon/vmware/cmddiscovery.pm +++ b/connectors/vmware/src/centreon/vmware/cmddiscovery.pm @@ -25,7 +25,7 @@ use base qw(centreon::vmware::cmdbase); use strict; use warnings; use centreon::vmware::common; -use centreon::class::cisTags; +use centreon::vmware::cisTags; sub new { my ($class, %options) = @_; @@ -92,7 +92,7 @@ sub run { } if (defined($self->{tags})) { - my $cisTags = centreon::class::cisTags->new(); + my $cisTags = centreon::vmware::cisTags->new(); $cisTags->configuration( url => $self->{connector}->{config_vsphere_url}, username => $self->{connector}->{config_vsphere_user}, diff --git a/connectors/vmware/src/centreon/class/http/backend/curl.pm b/connectors/vmware/src/centreon/vmware/http/backend/curl.pm similarity index 98% rename from connectors/vmware/src/centreon/class/http/backend/curl.pm rename to connectors/vmware/src/centreon/vmware/http/backend/curl.pm index 9c95d29b2..6d746f913 100644 --- a/connectors/vmware/src/centreon/class/http/backend/curl.pm +++ b/connectors/vmware/src/centreon/vmware/http/backend/curl.pm @@ -18,13 +18,13 @@ # limitations under the License. # -package centreon::class::http::backend::curl; +package centreon::vmware::http::backend::curl; use strict; use warnings; use URI; use Net::Curl::Easy; -use centreon::class::http::backend::curlconstants; +use centreon::vmware::http::backend::curlconstants; sub new { my ($class, %options) = @_; @@ -39,7 +39,7 @@ sub new { sub check_options { my ($self, %options) = @_; - $self->{constant_cb} = \¢reon::class::http::backend::curlconstants::get_constant_value; + $self->{constant_cb} = \¢reon::vmware::http::backend::curlconstants::get_constant_value; if (!defined($options{request}->{curl_opt})) { $options{request}->{curl_opt} = []; diff --git a/connectors/vmware/src/centreon/class/http/backend/curlconstants.pm b/connectors/vmware/src/centreon/vmware/http/backend/curlconstants.pm similarity index 94% rename from connectors/vmware/src/centreon/class/http/backend/curlconstants.pm rename to connectors/vmware/src/centreon/vmware/http/backend/curlconstants.pm index 1f78aa86d..8e409c009 100644 --- a/connectors/vmware/src/centreon/class/http/backend/curlconstants.pm +++ b/connectors/vmware/src/centreon/vmware/http/backend/curlconstants.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::class::http::backend::curlconstants; +package centreon::vmware::http::backend::curlconstants; use strict; use warnings; diff --git a/connectors/vmware/src/centreon/class/http/backend/lwp.pm b/connectors/vmware/src/centreon/vmware/http/backend/lwp.pm similarity index 98% rename from connectors/vmware/src/centreon/class/http/backend/lwp.pm rename to connectors/vmware/src/centreon/vmware/http/backend/lwp.pm index de490efa2..9f718d624 100644 --- a/connectors/vmware/src/centreon/class/http/backend/lwp.pm +++ b/connectors/vmware/src/centreon/vmware/http/backend/lwp.pm @@ -18,11 +18,11 @@ # limitations under the License. # -package centreon::class::http::backend::lwp; +package centreon::vmware::http::backend::lwp; use strict; use warnings; -use centreon::class::http::backend::useragent; +use centreon::vmware::http::backend::useragent; use URI; use IO::Socket::SSL; diff --git a/connectors/vmware/src/centreon/class/http/backend/useragent.pm b/connectors/vmware/src/centreon/vmware/http/backend/useragent.pm similarity index 92% rename from connectors/vmware/src/centreon/class/http/backend/useragent.pm rename to connectors/vmware/src/centreon/vmware/http/backend/useragent.pm index 2a9a1c2c2..228638c2c 100644 --- a/connectors/vmware/src/centreon/class/http/backend/useragent.pm +++ b/connectors/vmware/src/centreon/vmware/http/backend/useragent.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::class::http::backend::useragent; +package centreon::vmware::http::backend::useragent; use strict; use warnings; @@ -30,7 +30,7 @@ sub new { bless $self, $class; $self = LWP::UserAgent::new(@_); - $self->agent('centreon::class::http::backend::useragent'); + $self->agent('centreon::vmware::http::backend::useragent'); $self->{credentials} = $options{credentials} if defined($options{credentials}); $self->{username} = $options{username} if defined($options{username}); diff --git a/connectors/vmware/src/centreon/class/http/http.pm b/connectors/vmware/src/centreon/vmware/http/http.pm similarity index 91% rename from connectors/vmware/src/centreon/class/http/http.pm rename to connectors/vmware/src/centreon/vmware/http/http.pm index cd75c315e..f7ab98ae9 100644 --- a/connectors/vmware/src/centreon/class/http/http.pm +++ b/connectors/vmware/src/centreon/vmware/http/http.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::class::http::http; +package centreon::vmware::http::http; use strict; use warnings; @@ -86,17 +86,17 @@ sub check_options { if (!defined($self->{backend_lwp}) && !defined($self->{backend_curl})) { if ($options{request}->{http_backend} eq 'lwp' && $self->mymodule_load( - logger => $options{logger}, module => 'centreon::class::http::backend::lwp', - error_msg => "Cannot load module 'centreon::class::http::backend::lwp'." + logger => $options{logger}, module => 'centreon::vmware::http::backend::lwp', + error_msg => "Cannot load module 'centreon::vmware::http::backend::lwp'." ) == 0) { - $self->{backend_lwp} = centreon::class::http::backend::lwp->new(%options, logger => $self->{logger}); + $self->{backend_lwp} = centreon::vmware::http::backend::lwp->new(%options, logger => $self->{logger}); } if ($options{request}->{http_backend} eq 'curl' && $self->mymodule_load( - logger => $options{logger}, module => 'centreon::class::http::backend::curl', - error_msg => "Cannot load module 'centreon::class::http::backend::curl'." + logger => $options{logger}, module => 'centreon::vmware::http::backend::curl', + error_msg => "Cannot load module 'centreon::vmware::http::backend::curl'." ) == 0) { - $self->{backend_curl} = centreon::class::http::backend::curl->new(%options, logger => $self->{logger}); + $self->{backend_curl} = centreon::vmware::http::backend::curl->new(%options, logger => $self->{logger}); } } From fd7a06e753f9273f4f8186a71b6fd82d219c922d Mon Sep 17 00:00:00 2001 From: Luiz Costa Date: Thu, 18 Aug 2022 13:46:11 +0100 Subject: [PATCH 328/447] MON-14699 remove dependency already exists in other dependency --- connectors/vmware/ci/debian/control | 1 - 1 file changed, 1 deletion(-) diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control index 7cc486fa5..34391075b 100644 --- a/connectors/vmware/ci/debian/control +++ b/connectors/vmware/ci/debian/control @@ -15,7 +15,6 @@ Depends: ${misc:Depends}, libjson-xs-perl, liblwp-protocol-https-perl, libzmq-constants-perl, - libtext-template-perl, zmq-libzmq4-perl, perl-vmware-vsphere Description: Perl daemon to monitor VSphere Infrastructure From 21df301eff5665aee9adf8c9abd0e0ec87569127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Mon, 22 Aug 2022 16:22:13 +0200 Subject: [PATCH 329/447] chore(policy): remove policy to uses common .github files --- connectors/vmware/SECURITY.md | 96 ----------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 connectors/vmware/SECURITY.md diff --git a/connectors/vmware/SECURITY.md b/connectors/vmware/SECURITY.md deleted file mode 100644 index 1aed97a92..000000000 --- a/connectors/vmware/SECURITY.md +++ /dev/null @@ -1,96 +0,0 @@ -# Security Policy - -Centreon takes the security of our software products seriously. - -If you believe you have found a security vulnerability, please report it to us as described below. - -## Reporting a Vulnerability - -**Please do not report security vulnerabilities through public GitHub issues.** - -Send an email to security@centreon.com. If possible, encrypt your message with our PGP key below. - -You should receive a response within 48 hours. If for some reason you do not, please follow up via email to ensure we received your original message. - -To help us better understand the nature and scope of the possible issue, please describe as much as you can: - -* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) -* Full paths of source file(s) related to the manifestation of the issue -* The location of the affected source code (tag/branch/commit or direct URL) -* Any special configuration required to reproduce the issue -* Step-by-step instructions to reproduce the issue -* Proof-of-concept or exploit code (if possible) -* Impact of the issue, including how an attacker might exploit the issue - -## PGP information - -### Public key - -``` ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -oWAyTvK/VwbB77CTz1yTUSE= -=3kAj ------END PGP PUBLIC KEY BLOCK----- -``` - -| Tag | Value | -| -- | -- | -| ID | BEAF6EBF631106F9 | -| Type | RSA | -| Size | 4096 | -| Created | 2020-02-11 | -| Expires | 2021-02-10 | -| Cipher |AES-256| -| Fingerprint | C377 E9D5 2D5C 137D 3DD5 73B5 BEA F6EBF 6311 06F9 | - -## Bug bounty - -We don't have a bug bounty program but this is something we are thinking about. From 7c3a1bbe10f88d152c4e0e22e454be72805f5950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Wed, 21 Dec 2022 14:53:23 +0100 Subject: [PATCH 330/447] fix(chore): remove SQ analysis (#122) * fix(chore): remove SQ analysis * udpate license --- connectors/vmware/Jenkinsfile | 5 - connectors/vmware/LICENSE | 2 +- connectors/vmware/LICENSE.txt | 201 --------------------- connectors/vmware/sonar-project.properties | 3 - 4 files changed, 1 insertion(+), 210 deletions(-) delete mode 100644 connectors/vmware/LICENSE.txt delete mode 100644 connectors/vmware/sonar-project.properties diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile index 98a4a2cdb..1f050d4c7 100644 --- a/connectors/vmware/Jenkinsfile +++ b/connectors/vmware/Jenkinsfile @@ -8,11 +8,6 @@ stage('Source') { source = readProperties file: 'source.properties' env.VERSION = "${source.VERSION}" env.RELEASE = "${source.RELEASE}" - if (env.BRANCH_NAME == 'master') { - withSonarQubeEnv('SonarQubeDev') { - sh './centreon-build/jobs/vmware/vmware-analysis.sh' - } - } } } diff --git a/connectors/vmware/LICENSE b/connectors/vmware/LICENSE index 8f71f43fe..9ec83b986 100644 --- a/connectors/vmware/LICENSE +++ b/connectors/vmware/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright (C) 2008-2022 CENTREON - contact@centreon.com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/connectors/vmware/LICENSE.txt b/connectors/vmware/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/connectors/vmware/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/connectors/vmware/sonar-project.properties b/connectors/vmware/sonar-project.properties deleted file mode 100644 index 096a60f52..000000000 --- a/connectors/vmware/sonar-project.properties +++ /dev/null @@ -1,3 +0,0 @@ -sonar.projectKey=centreon-vmware -sonar.projectName=Centreon VMWare -sonar.sources=. From 29ee7d56b5a8b3a95f1cd51d9f9a869909a0bcd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chapron?= <34628915+sc979@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:43:12 +0100 Subject: [PATCH 331/447] chore(license): restore last translator name (#123) --- connectors/vmware/ci/debian/control | 2 +- connectors/vmware/ci/debian/copyright | 2 +- connectors/vmware/ci/scripts/vmware-deb-package.sh | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control index 34391075b..7a77d4973 100644 --- a/connectors/vmware/ci/debian/control +++ b/connectors/vmware/ci/debian/control @@ -1,7 +1,7 @@ Source: centreon-plugin-virtualization-vmware-daemon Section: net Priority: optional -Maintainer: Luiz Costa +Maintainer: Centreon Build-Depends: debhelper-compat (= 12) Standards-Version: 4.5.0 Homepage: https://www.centreon.com diff --git a/connectors/vmware/ci/debian/copyright b/connectors/vmware/ci/debian/copyright index 9d1ae47d8..8a4623a97 100644 --- a/connectors/vmware/ci/debian/copyright +++ b/connectors/vmware/ci/debian/copyright @@ -1,6 +1,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: centreon-plugin-virtualization-vmware-daemon -Upstream-Contact: Luiz Costa +Upstream-Contact: Centreon Source: https://www.centreon.com Files: * diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh index eb1c8756f..9926564b3 100755 --- a/connectors/vmware/ci/scripts/vmware-deb-package.sh +++ b/connectors/vmware/ci/scripts/vmware-deb-package.sh @@ -8,8 +8,8 @@ fi echo "################################################## PACKAGING COLLECT ##################################################" -AUTHOR="Luiz Costa" -AUTHOR_EMAIL="me@luizgustavo.pro.br" +AUTHOR="Centreon" +AUTHOR_EMAIL="contact@centreon.com" if [ -d /build ]; then rm -rf /build From 1de2f33a85d5ad4c31b836e684b222cf00bd4394 Mon Sep 17 00:00:00 2001 From: Laurent Pinsivy Date: Wed, 15 Feb 2023 13:49:48 +0100 Subject: [PATCH 332/447] MON-14383-add-missing-perl-dependency (#125) --- connectors/vmware/ci/debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control index 7a77d4973..1a14ed6cb 100644 --- a/connectors/vmware/ci/debian/control +++ b/connectors/vmware/ci/debian/control @@ -14,6 +14,7 @@ Depends: ${misc:Depends}, libnet-curl-perl, libjson-xs-perl, liblwp-protocol-https-perl, + libtext-template-perl, libzmq-constants-perl, zmq-libzmq4-perl, perl-vmware-vsphere From ecb56350d4832306f00506bf217cbe3e63987085 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Thu, 16 Feb 2023 08:09:18 +0000 Subject: [PATCH 333/447] (plugin) hardware::ups::riello::snmp - new (#4223) --- .../deb.json | 5 + .../pkg.json | 10 + .../rpm.json | 5 + src/hardware/ups/riello/snmp/mode/alarms.pm | 88 ++++++++ src/hardware/ups/riello/snmp/mode/battery.pm | 183 +++++++++++++++++ .../ups/riello/snmp/mode/inputlines.pm | 137 +++++++++++++ .../ups/riello/snmp/mode/outputlines.pm | 188 ++++++++++++++++++ src/hardware/ups/riello/snmp/plugin.pm | 50 +++++ 8 files changed, 666 insertions(+) create mode 100644 packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/deb.json create mode 100644 packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/pkg.json create mode 100644 packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/rpm.json create mode 100644 src/hardware/ups/riello/snmp/mode/alarms.pm create mode 100644 src/hardware/ups/riello/snmp/mode/battery.pm create mode 100644 src/hardware/ups/riello/snmp/mode/inputlines.pm create mode 100644 src/hardware/ups/riello/snmp/mode/outputlines.pm create mode 100644 src/hardware/ups/riello/snmp/plugin.pm diff --git a/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/deb.json b/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/deb.json new file mode 100644 index 000000000..663aaaceb --- /dev/null +++ b/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libsnmp-perl" + ] +} \ No newline at end of file diff --git a/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/pkg.json b/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/pkg.json new file mode 100644 index 000000000..d6e51a2cf --- /dev/null +++ b/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/pkg.json @@ -0,0 +1,10 @@ +{ + "pkg_name": "centreon-plugin-Hardware-Ups-Riello-Snmp", + "pkg_summary": "Centreon Plugin", + "plugin_name": "centreon_ups_riello_snmp.pl", + "files": [ + "centreon/plugins/script_snmp.pm", + "centreon/plugins/snmp.pm", + "hardware/ups/riello/snmp/" + ] +} diff --git a/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/rpm.json b/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/rpm.json new file mode 100644 index 000000000..418a331fc --- /dev/null +++ b/packaging/centreon-plugin-Hardware-Ups-Riello-Snmp/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(SNMP)" + ] +} \ No newline at end of file diff --git a/src/hardware/ups/riello/snmp/mode/alarms.pm b/src/hardware/ups/riello/snmp/mode/alarms.pm new file mode 100644 index 000000000..7327df94b --- /dev/null +++ b/src/hardware/ups/riello/snmp/mode/alarms.pm @@ -0,0 +1,88 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::ups::riello::snmp::mode::alarms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'alarms-current', nlabel => 'alarms.current.count', set => { + key_values => [ { name => 'current_alarms' } ], + output_template => 'current alarms: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ] +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_rupsAlarmsPresent = '.1.3.6.1.4.1.5491.10.1.6.1.0'; + my $snmp_result = $options{snmp}->get_leef( + oids => [ $oid_rupsAlarmsPresent ], + nothing_quit => 1 + ); + + $self->{global} = { + current_alarms => $snmp_result->{$oid_rupsAlarmsPresent} + }; +} + +1; + +__END__ + +=head1 MODE + +Check current alarms. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'alarms-current'. + +=back + +=cut diff --git a/src/hardware/ups/riello/snmp/mode/battery.pm b/src/hardware/ups/riello/snmp/mode/battery.pm new file mode 100644 index 000000000..061d60482 --- /dev/null +++ b/src/hardware/ups/riello/snmp/mode/battery.pm @@ -0,0 +1,183 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::ups::riello::snmp::mode::battery; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf('battery status is %s', $self->{result_values}->{status}); +} + +sub custom_load_output { + my ($self, %options) = @_; + + return sprintf( + 'charge remaining: %s%% (%s minutes remaining)', + $self->{result_values}->{charge_remain}, + $self->{result_values}->{minute_remain} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { + label => 'status', + type => 2, + unknown_default => '%{status} =~ /unknown/i', + warning_default => '%{status} =~ /low/i', + critical_default => '%{status} =~ /depleted/i', + set => { + key_values => [ { name => 'status' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'charge-remaining', nlabel => 'battery.charge.remaining.percent', set => { + key_values => [ { name => 'charge_remain' }, { name => 'minute_remain' } ], + closure_custom_output => $self->can('custom_load_output'), + perfdatas => [ + { template => '%s', min => 0, max => 100, unit => '%' } + ] + } + }, + { label => 'charge-remaining-minutes', nlabel => 'battery.charge.remaining.minutes', display_ok => 0, set => { + key_values => [ { name => 'minute_remain', no_value => 'unknown' } ], + output_template => 'minutes remaining: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'current', nlabel => 'battery.current.ampere', display_ok => 0, set => { + key_values => [ { name => 'current', no_value => 0 } ], + output_template => 'current: %s A', + perfdatas => [ + { template => '%s', min => 0, unit => 'A' } + ] + } + }, + { label => 'voltage', nlabel => 'battery.voltage.volt', display_ok => 0, set => { + key_values => [ { name => 'voltage', no_value => 0 } ], + output_template => 'voltage: %s V', + perfdatas => [ + { template => '%s', unit => 'V' } + ] + } + }, + { label => 'temperature', nlabel => 'battery.temperature.celsius', display_ok => 0, set => { + key_values => [ { name => 'temperature', no_value => 0 } ], + output_template => 'temperature: %s C', + perfdatas => [ + { template => '%s', unit => 'C' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $map_status = { + 1 => 'unknown', 2 => 'normal', 3 => 'low', 4 => 'depleted' +}; + +my $mapping = { + status => { oid => '.1.3.6.1.4.1.5491.10.1.2.1', map => $map_status }, # rupsBatteryStatus + minute_remain => { oid => '.1.3.6.1.4.1.5491.10.1.2.3' }, # rupsEstimatedMinutesRemaining + charge_remain => { oid => '.1.3.6.1.4.1.5491.10.1.2.4' }, # rupsEstimatedChargeRemaining + voltage => { oid => '.1.3.6.1.4.1.5491.10.1.2.5' }, # rupsBatteryVoltage (dV) + current => { oid => '.1.3.6.1.4.1.5491.10.1.2.6' }, # rupsBatteryCurrent + temperature => { oid => '.1.3.6.1.4.1.5491.10.1.2.7' } # rupsBatteryTemperature (degrees Centigrade) +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_leef( + oids => [ map($_->{oid} . '.0', values(%$mapping)) ] + ); + + $self->{global} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => 0); + $self->{global}->{current} = (defined($self->{global}->{current}) && $self->{global}->{current} =~ /\d/ && $self->{global}->{current} != -1 && $self->{global}->{current} != 65535) ? + $self->{global}->{current} * 0.1 : 0; + $self->{global}->{voltage} = (defined($self->{global}->{voltage}) && $self->{global}->{voltage} =~ /\d/ && $self->{global}->{voltage} != -1 && $self->{global}->{voltage} != 65535) ? + $self->{global}->{voltage} * 0.1 : 0; + $self->{global}->{temperature} = (defined($self->{global}->{temperature}) && $self->{global}->{temperature} =~ /\d/) ? $self->{global}->{temperature} : 0; + $self->{global}->{minute_remain} = (defined($self->{global}->{minute_remain}) && $self->{global}->{minute_remain} =~ /\d/ && $self->{global}->{minute_remain} != -1) ? $self->{global}->{minute_remain} : 'unknown'; + $self->{global}->{charge_remain} = (defined($self->{global}->{charge_remain}) && $self->{global}->{charge_remain} =~ /\d/) ? $self->{global}->{charge_remain} : undef; +} + +1; + +__END__ + +=head1 MODE + +Check battery status and charge remaining. + +=over 8 + +=item B<--unknown-status> + +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /low/i'). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /depleted/i'). +Can used special variables like: %{status} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'charge-remaining' (%), 'charge-remaining-minutes', +'current' (A), 'voltage' (V), 'temperature' (C). + +=back + +=cut diff --git a/src/hardware/ups/riello/snmp/mode/inputlines.pm b/src/hardware/ups/riello/snmp/mode/inputlines.pm new file mode 100644 index 000000000..9f3343fb0 --- /dev/null +++ b/src/hardware/ups/riello/snmp/mode/inputlines.pm @@ -0,0 +1,137 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::ups::riello::snmp::mode::inputlines; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_iline_output { + my ($self, %options) = @_; + + return "Input line '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'iline', type => 1, cb_prefix_output => 'prefix_iline_output', message_multiple => 'All input lines are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{iline} = [ + { label => 'current', nlabel => 'line.input.current.ampere', set => { + key_values => [ { name => 'current', no_value => 0 } ], + output_template => 'current: %.2f A', + perfdatas => [ + { template => '%.2f', min => 0, unit => 'A', label_extra_instance => 1 } + ] + } + }, + { label => 'voltage', nlabel => 'line.input.voltage.volt', set => { + key_values => [ { name => 'voltage', no_value => 0 } ], + output_template => 'voltage: %.2f V', + perfdatas => [ + { template => '%.2f', unit => 'V', label_extra_instance => 1 } + ] + } + }, + { label => 'frequence', nlabel => 'lines.input.frequence.hertz', set => { + key_values => [ { name => 'frequency', no_value => 0 } ], + output_template => 'frequence: %.2f Hz', + perfdatas => [ + { template => '%.2f', unit => 'Hz' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $mapping = { + frequency => { oid => '.1.3.6.1.4.1.5491.10.1.3.3.1.2' }, # rupsInputFrequency (dHZ) + voltage => { oid => '.1.3.6.1.4.1.5491.10.1.3.3.1.3' }, # rupsInputVoltage (dV) + current => { oid => '.1.3.6.1.4.1.5491.10.1.3.3.1.4' } # rupsInputCurrent (dA) +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_rupsInputEntry = '.1.3.6.1.4.1.5491.10.1.3.3.1'; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_rupsInputEntry, + nothing_quit => 1 + ); + + $self->{iline} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$oid_rupsInputEntry\.\d+\.(.*)$/); + my $instance = $1; + next if (defined($self->{iline}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + foreach ('current', 'voltage', 'frequency') { + $result->{$_} = 0 if (defined($result->{$_}) && ( + $result->{$_} eq '' || $result->{$_} == -1 || $result->{$_} == 65535 || $result->{$_} == 655350)); + $result->{$_} = $_ eq 'voltage' ? $result->{$_} : $result->{$_} * 0.1; + } + + $self->{iline}->{$instance} = { + display => $instance, + %$result + }; + } + + if (scalar(keys %{$self->{iline}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No input lines found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check input lines. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'frequence', 'voltage', 'current'. + +=back + +=cut diff --git a/src/hardware/ups/riello/snmp/mode/outputlines.pm b/src/hardware/ups/riello/snmp/mode/outputlines.pm new file mode 100644 index 000000000..0e1239d24 --- /dev/null +++ b/src/hardware/ups/riello/snmp/mode/outputlines.pm @@ -0,0 +1,188 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::ups::riello::snmp::mode::outputlines; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Output source status is '%s'", $self->{result_values}->{status}); +} + +sub prefix_oline_output { + my ($self, %options) = @_; + + return "Output line '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'oline', type => 1, cb_prefix_output => 'prefix_oline_output', message_multiple => 'All output lines are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { + label => 'source-status', + type => 2, + set => { + key_values => [ { name => 'status' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{oline} = [ + { label => 'load', nlabel => 'line.output.load.percentage', set => { + key_values => [ { name => 'percent_load' } ], + output_template => 'load: %.2f %%', + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1 } + ] + } + }, + { label => 'current', nlabel => 'line.output.current.ampere', set => { + key_values => [ { name => 'current' } ], + output_template => 'current: %.2f A', + perfdatas => [ + { template => '%.2f', min => 0, unit => 'A', label_extra_instance => 1 } + ] + } + }, + { label => 'voltage', nlabel => 'line.output.voltage.volt', set => { + key_values => [ { name => 'voltage' } ], + output_template => 'voltage: %.2f V', + perfdatas => [ + { template => '%.2f', unit => 'V', label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'ignore-zero-counters' => { name => 'ignore_zero_counters' } + }); + + return $self; +} + +my $map_status = { + 1 => 'other', 2 => 'none', + 3 => 'normal', 4 => 'bypass', 5 => 'battery', + 6 => 'booster', 7 => 'reducer' +}; + +my $mapping = { + voltage => { oid => '.1.3.6.1.4.1.5491.10.1.4.4.1.2' }, # rupsOutputVoltage (Volt) + current => { oid => '.1.3.6.1.4.1.5491.10.1.4.4.1.3' }, # rupsOutputCurrent (dA) + percent_load => { oid => '.1.3.6.1.4.1.5491.10.1.4.4.1.5' } # rupsOutputPercentLoad +}; +my $mapping2 = { + status => { oid => '.1.3.6.1.4.1.5491.10.1.4.1', map => $map_status } # rupsOutputSource +}; +my $tables = { + rupsOutput => '.1.3.6.1.4.1.5491.10.1.4', + rupsOutputEntry => '.1.3.6.1.4.1.5491.10.1.4.4.1' +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table( + oid => $tables->{rupsOutput}, + end => $mapping->{percent_load}->{oid}, + nothing_quit => 1 + ); + + $self->{oline} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$tables->{rupsOutputEntry}\.\d+\.(.*)$/); + my $instance = $1; + next if (defined($self->{oline}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + foreach (keys %$result) { + delete $result->{$_} if ( + (defined($self->{option_results}->{ignore_zero_counters}) && $result->{$_} == 0) || + ($result->{$_} == -1 || $result->{$_} == 65535) + ); + } + $result->{current} *= 0.1 if (defined($result->{current})); + if (scalar(keys %$result) > 0) { + $self->{oline}->{$instance} = { display => $instance, %$result }; + } + } + + $self->{global} = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => 0); +} + +1; + +__END__ + +=head1 MODE + +Check output lines. + +=over 8 + +=item B<--ignore-zero-counters> + +Ignore counters equals to 0. + +=item B<--unknown-source-status> + +Set unknown threshold for status. +Can used special variables like: %{status} + +=item B<--warning-source-status> + +Set warning threshold for status. +Can used special variables like: %{status} + +=item B<--critical-source-status> + +Set critical threshold for status. +Can used special variables like: %{status} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'load', 'voltage', 'current'. + +=back + +=cut diff --git a/src/hardware/ups/riello/snmp/plugin.pm b/src/hardware/ups/riello/snmp/plugin.pm new file mode 100644 index 000000000..fc5296904 --- /dev/null +++ b/src/hardware/ups/riello/snmp/plugin.pm @@ -0,0 +1,50 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::ups::riello::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'alarms' => 'hardware::ups::riello::snmp::mode::alarms', + 'battery' => 'hardware::ups::riello::snmp::mode::battery', + 'input-lines' => 'hardware::ups::riello::snmp::mode::inputlines', + 'output-lines' => 'hardware::ups::riello::snmp::mode::outputlines' + }; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Riello UPS in SNMP. + +=cut From 6466bff511be7604335f897529cc5dfd52734c78 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 17 Feb 2023 11:18:25 +0100 Subject: [PATCH 334/447] fix(ci): fix plugins delivery to debian and artifactory (#4230) --- .github/actions/deb-delivery/action.yml | 14 +++++++++----- .github/actions/rpm-delivery/action.yml | 9 +++++++++ .github/workflows/plugin-delivery.yml | 13 +++++++++---- .github/workflows/plugins.yml | 5 +++-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/.github/actions/deb-delivery/action.yml b/.github/actions/deb-delivery/action.yml index 058a7db2b..f03a28b5b 100644 --- a/.github/actions/deb-delivery/action.yml +++ b/.github/actions/deb-delivery/action.yml @@ -4,11 +4,11 @@ inputs: distrib: description: "The distribution used for packaging" required: true - artifactory_username: - description: The artifactory username + nexus_username: + description: The nexus username required: true - artifactory_password: - description: The artifactory password + nexus_password: + description: The nexus password required: true version: description: "Centreon packaged version" @@ -22,6 +22,9 @@ inputs: stability: description: "The package stability (stable, testing, unstable)" required: true + artifactory_token: + description: "token for artifactory" + required: true runs: using: "composite" @@ -42,6 +45,7 @@ runs: FOLDER_SUFFIX="" fi - find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 curl -u "${{ inputs.artifactory_username }}":"${{ inputs.artifactory_password }}" -H "Content-Type: multipart/form-data" --data-binary "@%" https://apt.centreon.com/repository/$MAJOR$FOLDER_SUFFIX/ + find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 curl --fail -v -u "${{ inputs.nexus_username }}":"${{ inputs.nexus_password }}" -H "Content-Type: multipart/form-data" --data-binary "@%" https://apt.centreon.com/repository/$MAJOR$FOLDER_SUFFIX/ + find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 curl --fail -v -H "Authorization: Bearer ${{ inputs.artifactory_token }}" -X PUT "https://centreon.jfrog.io/artifactory/apt-$MAJOR-${{ inputs.stability }}/pool/%;deb.distribution=${{ inputs.distrib }};deb.component=main;deb.architecture=all" -T "%" done shell: bash diff --git a/.github/actions/rpm-delivery/action.yml b/.github/actions/rpm-delivery/action.yml index aab466b21..36c9304bd 100644 --- a/.github/actions/rpm-delivery/action.yml +++ b/.github/actions/rpm-delivery/action.yml @@ -31,6 +31,9 @@ inputs: stability: description: "The package stability (stable, testing, unstable)" required: true + artifactory_token: + description: "token for artifactory" + required: true runs: using: "composite" @@ -68,12 +71,18 @@ runs: if [ "$REPOTYPE" == "stable" ]; then TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/RPMS" + ARTIFACTORY_TARGET="https://centreon.jfrog.io/artifactory/rpm/$PROJECT_PATH/$MAJOR/$DISTRIB/${{ inputs.stability }}/$ARCH" else FOLDER="centreon-$PROJECT-$VERSION-$RELEASE" TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/$PROJECT/$FOLDER" PROJECT_LOCATION="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/$PROJECT" + ARTIFACTORY_TARGET="https://centreon.jfrog.io/artifactory/rpm/$PROJECT_PATH/$MAJOR/$DISTRIB/${{ inputs.stability }}/$ARCH/$PROJECT/$FOLDER" fi + for FILE in $FILES; do + curl --fail -v -H "Authorization: Bearer ${{ inputs.artifactory_token }}" -X PUT "$ARTIFACTORY_TARGET/$FILE" -T "./$FILE" + done + echo "[DEBUG] - Folder: $FOLDER" echo "[DEBUG] - Project : $PROJECT" echo "[DEBUG] - Target : $TARGET" diff --git a/.github/workflows/plugin-delivery.yml b/.github/workflows/plugin-delivery.yml index e3406ec24..1263bf83c 100644 --- a/.github/workflows/plugin-delivery.yml +++ b/.github/workflows/plugin-delivery.yml @@ -14,9 +14,9 @@ on: type: string required: true secrets: - artifactory_username: + nexus_username: required: true - artifactory_password: + nexus_password: required: true update_repo_path: description: "The update repo script path" @@ -30,6 +30,9 @@ on: yum_repo_key: description: "The repo key" required: true + artifactory_token: + description: "The artifactory token" + required: true jobs: deliver-rpm: @@ -54,6 +57,7 @@ jobs: yum_repo_address: ${{ secrets.yum_repo_address }} yum_repo_key: ${{ secrets.yum_repo_key }} stability: ${{ inputs.stability }} + artifactory_token: ${{ secrets.artifactory_token }} deliver-deb: runs-on: [self-hosted, common] @@ -71,7 +75,8 @@ jobs: distrib: ${{ matrix.distrib }} version: ${{ inputs.version }} release: ${{ inputs.release }} - artifactory_username: ${{ secrets.artifactory_username }} - artifactory_password: ${{ secrets.artifactory_password }} + nexus_username: ${{ secrets.nexus_username }} + nexus_password: ${{ secrets.nexus_password }} cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} stability: ${{ inputs.stability }} + artifactory_token: ${{ secrets.artifactory_token }} diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 70bfa301d..b98977c66 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -107,9 +107,10 @@ jobs: release: ${{ needs.get-environment.outputs.release }} stability: ${{ needs.get-environment.outputs.stability }} secrets: - artifactory_username: ${{ secrets.NEXUS_USER }} - artifactory_password: ${{ secrets.NEXUS_PASSWD }} + nexus_username: ${{ secrets.NEXUS_USERNAME }} + nexus_password: ${{ secrets.NEXUS_PASSWORD }} update_repo_path: ${{ secrets.UPDATE_REPO_PATH }} cloudfront_id: ${{ secrets.CLOUDFRONT_ID }} yum_repo_address: ${{ secrets.YUM_REPO_ADDRESS }} yum_repo_key: ${{ secrets.YUM_REPO_KEY }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} From f18c26cd194e12c6c40f7dcc0e708fa5fb827d69 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 17 Feb 2023 13:34:43 +0000 Subject: [PATCH 335/447] (plugin) apps::protocols::cifs - mode files fix compilation (#4231) --- src/apps/protocols/cifs/mode/files.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/protocols/cifs/mode/files.pm b/src/apps/protocols/cifs/mode/files.pm index e563e24b3..4d174d504 100644 --- a/src/apps/protocols/cifs/mode/files.pm +++ b/src/apps/protocols/cifs/mode/files.pm @@ -118,7 +118,7 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - 'filter-file:s' => { name => 'filter_file' } + 'filter-file:s' => { name => 'filter_file' }, 'directory:s@' => { name => 'directory' }, 'file:s@' => { name => 'file' }, 'max-depth:s' => { name => 'max_depth', default => 0 }, From 0f2d3ec41b22d4539c0ef4640a94ad8c4564c74a Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 17 Feb 2023 15:27:27 +0000 Subject: [PATCH 336/447] (plugin) notification::centreon::opentickets::api - use http common options (#4234) --- src/notification/centreon/opentickets/api/custom/api.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/notification/centreon/opentickets/api/custom/api.pm b/src/notification/centreon/opentickets/api/custom/api.pm index 5949a2eab..aeed610b3 100644 --- a/src/notification/centreon/opentickets/api/custom/api.pm +++ b/src/notification/centreon/opentickets/api/custom/api.pm @@ -57,7 +57,7 @@ sub new { $self->{output} = $options{output}; $self->{http} = centreon::plugins::http->new(%options); - $self->{cache} = centreon::plugins::statefile->new(%options); + $self->{cache} = centreon::plugins::statefile->new(%options, default_backend => 'curl'); return $self; } @@ -138,7 +138,8 @@ sub settings { $self->{http}->set_options( hostname => $self->{api_hostname}, port => $self->{api_port}, - proto => $self->{api_proto} + proto => $self->{api_proto}, + %{$self->{option_results}} ); } From 54277ec33b7ee70bb1ed1187f0dc5c51972c1a71 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 17 Feb 2023 15:27:41 +0000 Subject: [PATCH 337/447] (plugin) hardware::ups::riello::snmp - fix perfdata name (#4228) --- src/hardware/ups/riello/snmp/mode/inputlines.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/ups/riello/snmp/mode/inputlines.pm b/src/hardware/ups/riello/snmp/mode/inputlines.pm index 9f3343fb0..4604ddd3a 100644 --- a/src/hardware/ups/riello/snmp/mode/inputlines.pm +++ b/src/hardware/ups/riello/snmp/mode/inputlines.pm @@ -55,7 +55,7 @@ sub set_counters { ] } }, - { label => 'frequence', nlabel => 'lines.input.frequence.hertz', set => { + { label => 'frequence', nlabel => 'line.input.frequence.hertz', set => { key_values => [ { name => 'frequency', no_value => 0 } ], output_template => 'frequence: %.2f Hz', perfdatas => [ From 2683d38e39bacf92d1a89f6da6e8d7d83b10a8c5 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Thu, 23 Feb 2023 17:24:11 +0100 Subject: [PATCH 338/447] chore(ci): move to harbor docker registry (#4237) --- .github/actions/package/action.yml | 27 +++++++++++-------- .github/actions/runner-docker/action.yml | 19 +++++++------ .../docker/Dockerfile.packaging-plugins-alma8 | 4 ++- .../docker/Dockerfile.packaging-plugins-alma9 | 4 ++- .../Dockerfile.packaging-plugins-bullseye | 4 ++- .../Dockerfile.packaging-plugins-centos7 | 4 ++- .../docker-builder-packaging-plugins.yml | 15 ++++++----- .github/workflows/plugin-package.yml | 9 ++++--- .github/workflows/plugins.yml | 4 +-- 9 files changed, 54 insertions(+), 36 deletions(-) diff --git a/.github/actions/package/action.yml b/.github/actions/package/action.yml index 95bbf62e4..5883ca2d5 100644 --- a/.github/actions/package/action.yml +++ b/.github/actions/package/action.yml @@ -27,11 +27,14 @@ inputs: sign: description: Wether to sign the package or not default: "" - artifactory_username: - description: The artifactory username + registry_url: + description: Docker registry url required: true - artifactory_password: - description: The artifactory password + registry_username: + description: Docker registry username + required: true + registry_password: + description: Docker registry password required: true runs: @@ -41,9 +44,9 @@ runs: - name: Login to Registry uses: docker/login-action@v2 with: - registry: docker.centreon.com - username: ${{ inputs.artifactory_username }} - password: ${{ inputs.artifactory_password }} + registry: ${{ inputs.registry_url }} + username: ${{ inputs.registry_username }} + password: ${{ inputs.registry_password }} - name: Package uses: ./.github/actions/runner-docker @@ -51,8 +54,9 @@ runs: script_name: ${{ inputs.script_name }} image_name: ${{ inputs.image_name }} image_version: latest - artifactory_username: ${{ inputs.artifactory_username }} - artifactory_password: ${{ inputs.artifactory_password }} + registry_url: ${{ inputs.registry_url }} + registry_username: ${{ inputs.registry_username }} + registry_password: ${{ inputs.registry_password }} params: ${{ inputs.version }} ${{ inputs.release }} "${{ inputs.plugins }}" - name: Sign @@ -62,8 +66,9 @@ runs: script_name: rpm-signing image_name: rpm-signing image_version: ubuntu - artifactory_username: ${{ inputs.artifactory_username }} - artifactory_password: ${{ inputs.artifactory_password }} + registry_url: ${{ inputs.registry_url }} + registry_username: ${{ inputs.registry_username }} + registry_password: ${{ inputs.registry_password }} - name: Cache packaged files uses: actions/cache@v3 diff --git a/.github/actions/runner-docker/action.yml b/.github/actions/runner-docker/action.yml index e0951f4e9..b457eee72 100644 --- a/.github/actions/runner-docker/action.yml +++ b/.github/actions/runner-docker/action.yml @@ -13,11 +13,14 @@ inputs: centreon_pat: description: "Secret" required: false - artifactory_username: - description: The artifactory username + registry_url: + description: Docker registry url required: true - artifactory_password: - description: The artifactory password + registry_username: + description: Docker registry username + required: true + registry_password: + description: Docker registry password required: true params: description: "params for script" @@ -28,9 +31,9 @@ runs: - name: Login to Registry (via runner) uses: docker/login-action@v2 with: - registry: docker.centreon.com - username: ${{ inputs.artifactory_username }} - password: ${{ inputs.artifactory_password }} + registry: ${{ inputs.registry_url }} + username: ${{ inputs.registry_username }} + password: ${{ inputs.registry_password }} - - run: docker run -i -e TOKEN=${{ inputs.centreon_pat }} --entrypoint /src/.github/scripts/${{ inputs.script_name }}.sh -v "$PWD:/src" docker.centreon.com/${{ inputs.image_name }}:${{ inputs.image_version }} ${{ inputs.params }} + - run: docker run -i -e TOKEN=${{ inputs.centreon_pat }} --entrypoint /src/.github/scripts/${{ inputs.script_name }}.sh -v "$PWD:/src" ${{ inputs.registry_url }}/${{ inputs.image_name }}:${{ inputs.image_version }} ${{ inputs.params }} shell: bash diff --git a/.github/docker/Dockerfile.packaging-plugins-alma8 b/.github/docker/Dockerfile.packaging-plugins-alma8 index 517f727b1..5e162edb8 100644 --- a/.github/docker/Dockerfile.packaging-plugins-alma8 +++ b/.github/docker/Dockerfile.packaging-plugins-alma8 @@ -1,4 +1,6 @@ -FROM docker-proxy.centreon.com/almalinux:8 +ARG REGISTRY_URL + +FROM ${REGISTRY_URL}/almalinux:8 RUN < Date: Wed, 1 Mar 2023 14:13:16 +0000 Subject: [PATCH 339/447] (plugin) apps::centreon::local - mode bamservice make it work (#4242) --- src/apps/centreon/local/mode/bamservice.pm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/apps/centreon/local/mode/bamservice.pm b/src/apps/centreon/local/mode/bamservice.pm index 19bb9a114..79cb5b935 100644 --- a/src/apps/centreon/local/mode/bamservice.pm +++ b/src/apps/centreon/local/mode/bamservice.pm @@ -57,7 +57,16 @@ sub run { my ($self, %options) = @_; my $sql = centreon::plugins::dbi->new(options => $self->{options}, output => $self->{output}, nooptions => 1); - $sql->{data_source} = 'mysql:host=' . $centreon_config->{db_host} . 'port=' . $centreon_config->{db_port}; + + my $port = ''; + if (defined($centreon_config->{db_port})) { + $port = ';port=' . $centreon_config->{db_port}; + } elsif ($centreon_config->{db_host} =~ /:(\d+)$/) { + $port = ';port=' . $1; + $centreon_config->{db_host} =~ s/:\d+$//; + } + + $sql->{data_source} = 'mysql:host=' . $centreon_config->{db_host} . $port; $sql->{username} = $centreon_config->{db_user}; $sql->{password} = $centreon_config->{db_passwd}; $sql->connect(); @@ -65,7 +74,7 @@ sub run { $sql->query(query => "SELECT `name`,`current_level`,`level_w`,`level_c` FROM " . $centreon_config->{centreon_db} . ".`mod_bam` WHERE `ba_id` = '" . $self->{option_results}->{bam_id} . "'" ); - my ($name, $current_level, $level_w, $level_c) = $self->{sql}->fetchrow_array(); + my ($name, $current_level, $level_w, $level_c) = $sql->fetchrow_array(); if (!defined($current_level)) { $self->{output}->add_option_msg(short_msg => "Cannot get bam information"); $self->{output}->option_exit(); From 83c1beb5f9e1151ce8a884b75bb4971edcae10f2 Mon Sep 17 00:00:00 2001 From: ponchoh Date: Thu, 2 Mar 2023 03:04:55 -0500 Subject: [PATCH 340/447] update(doc) emails (#4244) --- .github/issue_template.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index 8621ce438..16c79ac7a 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -9,10 +9,10 @@ To develop a Plugin/mode, we need the following: * SQL: requests * JMX: mbean names and attributes -If some parts of information are confidentials, please send them directly by email to qgarnier@centreon.com and sbomm@centreon.com. +If some parts of information are confidentials, please send them directly by email to qgarnier@centreon.com. Please note that all the developments are open-source. We can't give a date for the development, achievement or release. If it's a priority for you, -send us an email about it (qgarnier@centreon.com and sbomm@centreon.com) and we'll put you in touch with our company. +send us an email about it (qgarnier@centreon.com) and we'll put you in touch with our company. ## Bug/Question From 29414a4739d5cf73469fbca579f8e2dafa4fd1be Mon Sep 17 00:00:00 2001 From: itoussies <65223458+itoussies@users.noreply.github.com> Date: Fri, 3 Mar 2023 10:50:00 +0100 Subject: [PATCH 341/447] (plugin) apps::centreon::sql::mode::multiservices - allow host arrays in config file (#4251) --- src/apps/centreon/sql/mode/multiservices.pm | 65 +++++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/src/apps/centreon/sql/mode/multiservices.pm b/src/apps/centreon/sql/mode/multiservices.pm index 0ee270288..b57f226dc 100644 --- a/src/apps/centreon/sql/mode/multiservices.pm +++ b/src/apps/centreon/sql/mode/multiservices.pm @@ -367,6 +367,36 @@ my %map_service_state = ( 3 => 'unknown', ); + +sub manage_query { + my ($self, %options) = @_; + + my $query = "SELECT hosts.name, services.description, hosts.state as hstate, services.state as sstate, services.output as soutput + FROM centreon_storage.hosts, centreon_storage.services WHERE hosts.host_id=services.host_id + AND hosts.name NOT LIKE 'Module%' AND hosts.enabled=1 AND services.enabled=1 + AND hosts.name = '" . $options{host} . "' + AND services.description = '" . $options{service} . "'"; + + $self->{sql}->query(query => $query); + while ((my $row = $self->{sql}->fetchrow_hashref())) { + if (!exists($self->{instance_mode}->{inventory}->{hosts}->{$options{group}}->{$row->{name}})) { + push @{$self->{instance_mode}->{inventory}->{groups}->{$options{group}}->{'list_'.$map_host_state{$row->{hstate}}}} ,$row->{name}; + if (!defined($self->{hosts}->{$options{host}})) { + $self->{hosts}->{$options{host}} = 1; + $self->{totalhost}->{$map_host_state{$row->{hstate}}}++; + $self->{logicalgroups}->{$options{group}}->{$map_host_state{$row->{hstate}}}++; + } + } + push @{$self->{instance_mode}->{inventory}->{groups}->{$options{group}}->{'list_'.$map_service_state{$row->{sstate}}}}, $row->{name} . ${config_data}->{formatting}->{host_service_separator} . $row->{description}; + + $self->{instance_mode}->{inventory}->{hosts}->{$options{group}}->{$row->{name}} = $row->{hstate}; + $self->{instance_mode}->{inventory}->{services}{ $row->{name} . ${config_data}->{formatting}->{host_service_separator} . $row->{description} } = { state => $row->{sstate}, output => $row->{soutput} } ; + $self->{instance_mode}->{inventory}->{groups}->{$options{group}}->{$row->{name} . ${config_data}->{formatting}->{host_service_separator} . $row->{description}} = { state => $row->{sstate}, output => $row->{soutput} }; + $self->{totalservice}->{$map_service_state{$row->{sstate}}}++; + $self->{logicalgroups}->{$options{group}}->{$map_service_state{$row->{sstate}}}++; + } +} + sub manage_selection { my ($self, %options) = @_; # $options{sql} = sqlmode object @@ -374,6 +404,7 @@ sub manage_selection { $self->{sql}->connect(); $self->{groups} = {}; + $self->{hosts} = {}; if ($config_data->{counters}->{totalhosts} eq 'true') { push @{$self->{maps_counters_type}}, { @@ -435,26 +466,22 @@ sub manage_selection { up => 0, down => 0, unreachable => 0, ok => 0, warning => 0, critical => 0, unknown => 0 }; - foreach my $tuple (keys %{$config_data->{selection}->{$group}}) { - my $query = "SELECT hosts.name, services.description, hosts.state as hstate, services.state as sstate, services.output as soutput - FROM centreon_storage.hosts, centreon_storage.services WHERE hosts.host_id=services.host_id - AND hosts.name NOT LIKE 'Module%' AND hosts.enabled=1 AND services.enabled=1 - AND hosts.name = '" . $tuple . "' - AND services.description = '" . $config_data->{selection}->{$group}->{$tuple} . "'"; - $self->{sql}->query(query => $query); - while ((my $row = $self->{sql}->fetchrow_hashref())) { - if (!exists($self->{instance_mode}->{inventory}->{hosts}->{$group}->{$row->{name}})) { - push @{$self->{instance_mode}->{inventory}->{groups}->{$group}->{'list_'.$map_host_state{$row->{hstate}}}} ,$row->{name}; - $self->{totalhost}->{$map_host_state{$row->{hstate}}}++; - $self->{logicalgroups}->{$group}->{$map_host_state{$row->{hstate}}}++; + foreach my $host (keys %{$config_data->{selection}->{$group}}) { + if (ref($config_data->{selection}->{$group}->{$host}) eq "ARRAY") { + foreach my $service (@{$config_data->{selection}->{$group}->{$host}}) { + $self->manage_query( + group => $group, + host => $host, + service => $service + ); } - push @{$self->{instance_mode}->{inventory}->{groups}->{$group}->{'list_'.$map_service_state{$row->{sstate}}}}, $row->{name} . ${config_data}->{formatting}->{host_service_separator} . $row->{description}; - - $self->{instance_mode}->{inventory}->{hosts}->{$group}->{$row->{name}} = $row->{hstate}; - $self->{instance_mode}->{inventory}->{services}{ $row->{name} . ${config_data}->{formatting}->{host_service_separator} . $row->{description} } = { state => $row->{sstate}, output => $row->{soutput} } ; - $self->{instance_mode}->{inventory}->{groups}->{$group}->{$row->{name} . ${config_data}->{formatting}->{host_service_separator} . $row->{description}} = { state => $row->{sstate}, output => $row->{soutput} }; - $self->{totalservice}->{$map_service_state{$row->{sstate}}}++; - $self->{logicalgroups}->{$group}->{$map_service_state{$row->{sstate}}}++; + + } else { + $self->manage_query( + group => $group, + host => $host, + service => $config_data->{selection}->{$group}->{$host} + ); } } } From 843a27b2a3a2a0298386e9ccdf7861e0f8447f01 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 3 Mar 2023 10:54:34 +0100 Subject: [PATCH 342/447] chore(ci): upload to artifactory connectors repository (#4239) Refs: MON-16173 --- .github/actions/deb-delivery/action.yml | 13 +++++++++++-- .github/actions/rpm-delivery/action.yml | 18 +++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/.github/actions/deb-delivery/action.yml b/.github/actions/deb-delivery/action.yml index f03a28b5b..59bd779e5 100644 --- a/.github/actions/deb-delivery/action.yml +++ b/.github/actions/deb-delivery/action.yml @@ -35,7 +35,17 @@ runs: path: ./*.deb key: ${{ inputs.cache_key }} - - name: Publish DEBS to Nexus + - uses: jfrog/setup-jfrog-cli@v3 + env: + JF_URL: https://centreon.jfrog.io + JF_ACCESS_TOKEN: ${{ inputs.artifactory_token }} + + - name: Publish DEBs to artifactory + run: | + jf rt upload "*.deb" "apt-connectors-${{ inputs.stability }}/pool/" --deb "${{ inputs.distrib }}/main/all" + shell: bash + + - name: Publish DEBs to Nexus run: | for MAJOR in "22.04" "22.10"; do echo "Delivering to $MAJOR ${{ inputs.stability }}" @@ -46,6 +56,5 @@ runs: fi find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 curl --fail -v -u "${{ inputs.nexus_username }}":"${{ inputs.nexus_password }}" -H "Content-Type: multipart/form-data" --data-binary "@%" https://apt.centreon.com/repository/$MAJOR$FOLDER_SUFFIX/ - find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 curl --fail -v -H "Authorization: Bearer ${{ inputs.artifactory_token }}" -X PUT "https://centreon.jfrog.io/artifactory/apt-$MAJOR-${{ inputs.stability }}/pool/%;deb.distribution=${{ inputs.distrib }};deb.component=main;deb.architecture=all" -T "%" done shell: bash diff --git a/.github/actions/rpm-delivery/action.yml b/.github/actions/rpm-delivery/action.yml index 36c9304bd..a4d2dd614 100644 --- a/.github/actions/rpm-delivery/action.yml +++ b/.github/actions/rpm-delivery/action.yml @@ -44,6 +44,16 @@ runs: path: ./*.rpm key: ${{ inputs.cache_key }} + - uses: jfrog/setup-jfrog-cli@v3 + env: + JF_URL: https://centreon.jfrog.io + JF_ACCESS_TOKEN: ${{ inputs.artifactory_token }} + + - name: Publish RPMs to connectors repository + run: | + jf rt upload "*.rpm" "rpm-connectors/${{ inputs.distrib }}/${{ inputs.stability }}/noarch/" + shell: bash + - name: Setup awscli run: | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" @@ -51,7 +61,7 @@ runs: sudo ./aws/install shell: bash - - name: Publish RPMS + - name: Publish RPMs to standard repositories run: | FILES="*.rpm" @@ -71,18 +81,12 @@ runs: if [ "$REPOTYPE" == "stable" ]; then TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/RPMS" - ARTIFACTORY_TARGET="https://centreon.jfrog.io/artifactory/rpm/$PROJECT_PATH/$MAJOR/$DISTRIB/${{ inputs.stability }}/$ARCH" else FOLDER="centreon-$PROJECT-$VERSION-$RELEASE" TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/$PROJECT/$FOLDER" PROJECT_LOCATION="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/$PROJECT" - ARTIFACTORY_TARGET="https://centreon.jfrog.io/artifactory/rpm/$PROJECT_PATH/$MAJOR/$DISTRIB/${{ inputs.stability }}/$ARCH/$PROJECT/$FOLDER" fi - for FILE in $FILES; do - curl --fail -v -H "Authorization: Bearer ${{ inputs.artifactory_token }}" -X PUT "$ARTIFACTORY_TARGET/$FILE" -T "./$FILE" - done - echo "[DEBUG] - Folder: $FOLDER" echo "[DEBUG] - Project : $PROJECT" echo "[DEBUG] - Target : $TARGET" From 1fe0b32cfd28ae3900eca8de67d70646dd236979 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 6 Mar 2023 09:13:18 +0000 Subject: [PATCH 343/447] (plugin) hardware::ups::standard::rfc1628::snmp - perfdata v2 + threshold options (#4232) --- .../ups/standard/rfc1628/snmp/mode/alarms.pm | 66 ++++++++------- .../rfc1628/snmp/mode/batterystatus.pm | 12 +-- .../standard/rfc1628/snmp/mode/inputlines.pm | 63 ++++++-------- .../standard/rfc1628/snmp/mode/outputlines.pm | 2 +- .../rfc1628/snmp/mode/outputsource.pm | 84 ++++++++++++------- .../ups/standard/rfc1628/snmp/plugin.pm | 1 - 6 files changed, 126 insertions(+), 102 deletions(-) diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/alarms.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/alarms.pm index 7d75e0cf8..2ea0f5e3b 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/alarms.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/alarms.pm @@ -20,47 +20,52 @@ package hardware::ups::standard::rfc1628::snmp::mode::alarms; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'alarms-current', nlabel => 'alarms.current.count', set => { + key_values => [ { name => 'current_alarms' } ], + output_template => 'current alarms: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ] +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); -} -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $oid_upsAlarmsPresent = '.1.3.6.1.2.1.33.1.6.1.0'; - my $result = $self->{snmp}->get_leef(oids => [ $oid_upsAlarmsPresent ], nothing_quit => 1); + my $oid_upsAlarmsPresent = '.1.3.6.1.2.1.33.1.6.1.0'; + my $snmp_result = $options{snmp}->get_leef( + oids => [ $oid_upsAlarmsPresent ], + nothing_quit => 1 + ); - $self->{output}->output_add(severity => 'ok', - short_msg => 'No alarms'); - if ($result->{$oid_upsAlarmsPresent} > 0) { - $self->{output}->output_add(severity => 'critical', - short_msg => sprintf('%d Alarms (check your equipment to have more informations)', $result->{$oid_upsAlarmsPresent})); - } - $self->{output}->perfdata_add(label => 'alarms', - value => $result->{$oid_upsAlarmsPresent}, - min => 0); - - $self->{output}->display(); - $self->{output}->exit(); + $self->{global} = { + current_alarms => $snmp_result->{$oid_upsAlarmsPresent} + }; } 1; @@ -69,12 +74,15 @@ __END__ =head1 MODE -Check if Alarms present. -Need an example to do the display from 'upsAlarmTable'. If you have ;) -https://forge.centreon.com/issues/5377 +Check current alarms. =over 8 +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'alarms-current'. + =back =cut diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm index 79770873e..13657a760 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm @@ -67,7 +67,7 @@ sub set_counters { key_values => [ { name => 'charge_remain' }, { name => 'minute_remain' } ], closure_custom_output => $self->can('custom_load_output'), perfdatas => [ - { label => 'load', template => '%s', min => 0, max => 100, unit => '%' } + { template => '%s', min => 0, max => 100, unit => '%' } ] } }, @@ -75,7 +75,7 @@ sub set_counters { key_values => [ { name => 'minute_remain' } ], output_template => 'minutes remaining: %s', perfdatas => [ - { label => 'charge_remaining', template => '%s', min => 0, unit => 'minutes' } + { template => '%s', min => 0, unit => 'minutes' } ] } }, @@ -83,7 +83,7 @@ sub set_counters { key_values => [ { name => 'current', no_value => 0 } ], output_template => 'current: %s A', perfdatas => [ - { label => 'current', template => '%s', min => 0, unit => 'A' } + { template => '%s', min => 0, unit => 'A' } ] } }, @@ -91,7 +91,7 @@ sub set_counters { key_values => [ { name => 'voltage', no_value => 0 } ], output_template => 'voltage: %s V', perfdatas => [ - { label => 'voltage', template => '%s', unit => 'V' } + { template => '%s', unit => 'V' } ] } }, @@ -99,7 +99,7 @@ sub set_counters { key_values => [ { name => 'temperature', no_value => 0 } ], output_template => 'temperature: %s C', perfdatas => [ - { label => 'temp', template => '%s', unit => 'C' } + { template => '%s', unit => 'C' } ] } } @@ -108,7 +108,7 @@ sub set_counters { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/inputlines.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/inputlines.pm index fa8d103ad..876b69428 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/inputlines.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/inputlines.pm @@ -25,6 +25,12 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub prefix_line_output { + my ($self, %options) = @_; + + return "Input Line '" . $options{instance_value}->{display} . "' "; +} + sub set_counters { my ($self, %options) = @_; @@ -33,59 +39,47 @@ sub set_counters { ]; $self->{maps_counters}->{line} = [ - { label => 'frequence', set => { + { label => 'frequence', nlabel => 'line.input.frequence.hertz', set => { key_values => [ { name => 'upsInputFrequency' }, { name => 'display' } ], output_template => 'Frequence : %.2f Hz', perfdatas => [ - { label => 'frequence', value => 'upsInputFrequency', template => '%s', - unit => 'Hz', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', unit => 'Hz', label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'voltage', set => { + { label => 'voltage', nlabel => 'line.input.voltage.volt', set => { key_values => [ { name => 'upsInputVoltage' }, { name => 'display' } ], output_template => 'Voltage : %.2f V', perfdatas => [ - { label => 'voltage', value => 'upsInputVoltage', template => '%s', - unit => 'V', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', unit => 'V', label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'current', set => { + { label => 'current', nlabel => 'line.input.current.ampere', set => { key_values => [ { name => 'upsInputCurrent' }, { name => 'display' } ], output_template => 'Current : %.2f A', perfdatas => [ - { label => 'current', value => 'upsInputCurrent', template => '%s', - unit => 'A', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', unit => 'A', label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'power', set => { + { label => 'power', nlabel => 'line.input.power.watt', set => { key_values => [ { name => 'upsInputTruePower' }, { name => 'display' } ], output_template => 'Power : %.2f W', perfdatas => [ - { label => 'power', value => 'upsInputTruePower', template => '%s', - unit => 'W', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', unit => 'W', label_extra_instance => 1, instance_use => 'display' } + ] } - }, + } ]; } -sub prefix_line_output { - my ($self, %options) = @_; - - return "Input Line '" . $options{instance_value}->{display} . "' "; -} - sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } @@ -102,14 +96,14 @@ sub manage_selection { my $oid_upsInputEntry = '.1.3.6.1.2.1.33.1.3.3.1'; my $results = $options{snmp}->get_table(oid => $oid_upsInputEntry, nothing_quit => 1); - + $self->{line} = {}; foreach my $oid (keys %{$results}) { next if ($oid !~ /^(.*)\.(.*?)\.(.*?)$/); my ($base, $instance) = ($1 . '.' . $2, $3); next if (!defined($oids->{$base})); next if ($results->{$oid} !~ /\d/ || $results->{$oid} == 0); - + $self->{line}->{$instance} = { display => $instance } if (!defined($self->{line}->{$instance})); $self->{line}->{$instance}->{$oids->{$base}->{name}} = $results->{$oid} * $oids->{$base}->{factor}; } @@ -121,7 +115,7 @@ __END__ =head1 MODE -Check Input lines metrics (frequence, voltage, current and true power). +Check input lines metrics (frequence, voltage, current and true power). =over 8 @@ -130,14 +124,9 @@ Check Input lines metrics (frequence, voltage, current and true power). Only display some counters (regexp can be used). Example: --filter-counters='^power$' -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Threshold warning. -Can be: 'frequence', 'voltage', 'current', 'power'. - -=item B<--critical-*> - -Threshold critical. +Thresholds. Can be: 'frequence', 'voltage', 'current', 'power'. =back diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm index e459fd2fb..1acb21e13 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm @@ -82,7 +82,7 @@ sub set_counters { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm index 22a60b7eb..ba26ae07f 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm @@ -20,52 +20,65 @@ package hardware::ups::standard::rfc1628::snmp::mode::outputsource; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); -my %outputsource_status = ( - 1 => ['other', 'UNKNOWN'], - 2 => ['none', 'CRITICAL'], - 3 => ['normal', 'OK'], - 4 => ['bypass', 'WARNING'], - 5 => ['battery', 'WARNING'], - 6 => ['booster', 'WARNING'], - 7 => ['reducer', 'WARNING'], -); +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Output source status is '%s'", $self->{result_values}->{status}); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { + label => 'source-status', + type => 2, + unknown_default => '%{status} =~ /other/', + warning_default => '%{status} =~ /bypass|battery|booster|reducer/', + critical_default => '%{status} =~ /none/', + set => { + key_values => [ { name => 'status' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); -} -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - + my $map_status = { + 1 => 'other', 2 => 'none', + 3 => 'normal', 4 => 'bypass', 5 => 'battery', + 6 => 'booster', 7 => 'reducer' + }; + my $oid_upsOutputSource = '.1.3.6.1.2.1.33.1.4.1.0'; - - my $result = $self->{snmp}->get_leef(oids => [$oid_upsOutputSource], nothing_quit => 1); - my $status = $result->{'.1.3.6.1.2.1.33.1.4.1.0'}; - - $self->{output}->output_add(severity => ${$outputsource_status{$status}}[1], - short_msg => sprintf("Output source status is %s", ${$outputsource_status{$status}}[0])); + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_upsOutputSource], nothing_quit => 1); - $self->{output}->display(); - $self->{output}->exit(); + $self->{global} = { status => $map_status->{ $snmp_result->{$oid_upsOutputSource} } }; } 1; @@ -78,6 +91,21 @@ Check output source status. =over 8 +=item B<--unknown-source-status> + +Set unknown threshold for status (Default: '%{status} =~ /other/') +Can used special variables like: %{status} + +=item B<--warning-source-status> + +Set warning threshold for status (Default: '%{status} =~ /bypass|battery|booster|reducer/') +Can used special variables like: %{status} + +=item B<--critical-source-status> + +Set critical threshold for status (Default: '%{status} =~ /none/') +Can used special variables like: %{status} + =back =cut diff --git a/src/hardware/ups/standard/rfc1628/snmp/plugin.pm b/src/hardware/ups/standard/rfc1628/snmp/plugin.pm index b1e86b812..7290c1485 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/plugin.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/plugin.pm @@ -29,7 +29,6 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '0.1'; $self->{modes} = { 'alarms' => 'hardware::ups::standard::rfc1628::snmp::mode::alarms', 'battery-status' => 'hardware::ups::standard::rfc1628::snmp::mode::batterystatus', From fff4614e0d3939b4ab489f6e0691b849f3e906a0 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 7 Mar 2023 13:15:28 +0000 Subject: [PATCH 344/447] (plugin) apps::protocols::dns - fix no nameservers error (#4259) --- src/apps/protocols/dns/lib/dns.pm | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/apps/protocols/dns/lib/dns.pm b/src/apps/protocols/dns/lib/dns.pm index 04459ec83..126763013 100644 --- a/src/apps/protocols/dns/lib/dns.pm +++ b/src/apps/protocols/dns/lib/dns.pm @@ -76,24 +76,18 @@ sub connect { my ($self, %options) = @_; my %dns_options = (); - my $nameservers = []; if (defined($self->{option_results}->{nameservers})) { - $nameservers = [@{$self->{option_results}->{nameservers}}]; + $dns_options{nameservers} = [@{$self->{option_results}->{nameservers}}]; } - my $searchlist = []; if (defined($self->{option_results}->{searchlist})) { - $searchlist = [@{$self->{option_results}->{searchlist}}]; + $dns_options{searchlist} = [@{$self->{option_results}->{searchlist}}]; } foreach my $option (@{$self->{option_results}->{dns_options}}) { next if ($option !~ /^(.+?)=(.+)$/); $dns_options{$1} = $2; } - $handle = Net::DNS::Resolver->new( - nameservers => $nameservers, - searchlist => $searchlist, - %dns_options - ); + $handle = Net::DNS::Resolver->new(%dns_options); } 1; From b0871def2067686b0878a85614d35b7edf61f3cd Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 7 Mar 2023 15:02:11 +0000 Subject: [PATCH 345/447] (plugin) storage::nimble::restapi - mode volumes use full_name and add --filter-replication-role option (#4260) --- src/storage/nimble/restapi/mode/volumes.pm | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/storage/nimble/restapi/mode/volumes.pm b/src/storage/nimble/restapi/mode/volumes.pm index c75e8e762..a04efa1b4 100644 --- a/src/storage/nimble/restapi/mode/volumes.pm +++ b/src/storage/nimble/restapi/mode/volumes.pm @@ -63,11 +63,11 @@ sub set_counters { } }, { label => 'space-usage', nlabel => 'volume.space.usage.bytes', set => { - key_values => [ { name => 'used_space' }, { name => 'display' } ], + key_values => [ { name => 'used_space' } ], output_template => 'space used: %s %s', output_change_bytes => 1, perfdatas => [ - { template => '%d', min => 0, unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'display' } + { template => '%d', min => 0, unit => 'B', cast_int => 1, label_extra_instance => 1 } ] } }, @@ -130,7 +130,8 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - 'filter-name:s' => { name => 'filter_name' } + 'filter-name:s' => { name => 'filter_name' }, + 'filter-replication-role:s' => { name => 'filter_replication_role' } }); return $self; @@ -144,13 +145,19 @@ sub manage_selection { $self->{volumes} = {}; foreach (@{$results->{data}}) { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $_->{name} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping volume '" . $_->{name} . "': no matching filter.", debug => 1); + $_->{full_name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping volume '" . $_->{full_name} . "': no matching filter.", debug => 1); next; } + if (defined($self->{option_results}->{filter_replication_role}) && $self->{option_results}->{filter_replication_role} ne '' && + $_->{replication_role} !~ /$self->{option_results}->{filter_replication_role}/) { + $self->{output}->output_add(long_msg => "skipping volume '" . $_->{full_name} . "': no matching filter.", debug => 1); + next; + } + - $self->{volumes}->{ $_->{name} } = { - display => $_->{name}, + $self->{volumes}->{ $_->{full_name} } = { + display => $_->{full_name}, state => $_->{vol_state}, space_usage_level => $_->{space_usage_level}, used_space => $_->{total_usage_bytes}, @@ -188,6 +195,10 @@ Example: --filter-counters='status' Filter volume name (can be a regexp). +=item B<--filter-replication-role> + +Filter volumes by replication role (can be a regexp). + =item B<--unknown-status> Set unknown threshold for status. From 16c5cddafe88f0a9cfdb29b55081cde5a32521d6 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 7 Mar 2023 15:02:53 +0000 Subject: [PATCH 346/447] (plugin) os::linux::local - mode ntp fix filters (#4261) --- src/os/linux/local/mode/ntp.pm | 50 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/os/linux/local/mode/ntp.pm b/src/os/linux/local/mode/ntp.pm index 6fc62df15..fbd2d9ec1 100644 --- a/src/os/linux/local/mode/ntp.pm +++ b/src/os/linux/local/mode/ntp.pm @@ -243,11 +243,36 @@ sub manage_selection { } next if ($line !~ /$mode->{regexp}/); + my $entry = {}; my ($remote_peer, $peer_fate) = (centreon::plugins::misc::trim($2), centreon::plugins::misc::trim($1)); if ($mode->{type} eq 'chronyc') { $remote_peer = centreon::plugins::misc::trim($3); $peer_fate = centreon::plugins::misc::trim($2); + my ($type, $stratum, $poll, $reach, $lastRX, $offset) = ($1, $4, $5, $6, $7, $9); + $entry = { + display => $remote_peer, + rawstate => $peer_fate, + state => $state_map_chronyc{$peer_fate}, + stratum => centreon::plugins::misc::trim($stratum), + rawtype => centreon::plugins::misc::trim($type), + type => $type_map_chronyc{centreon::plugins::misc::trim($type)}, + reach => centreon::plugins::misc::trim($reach), + offset => centreon::plugins::misc::trim($offset) * $unit_map_chronyc{centreon::plugins::misc::trim($10)}, + }; + } else { + my ($refid, $stratum, $type, $last_time, $polling_intervall, $reach, $delay, $offset, $jitter) = ($3, $4, $5, $6, $7, $8, $9, $10, $11); + $entry = { + display => $remote_peer, + rawstate => $peer_fate, + state => $state_map_ntpq{$peer_fate}, + stratum => centreon::plugins::misc::trim($stratum), + rawtype => centreon::plugins::misc::trim($type), + type => $type_map_ntpq{centreon::plugins::misc::trim($type)}, + reach => centreon::plugins::misc::trim($reach), + offset => centreon::plugins::misc::trim($offset) + }; } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $remote_peer !~ /$self->{option_results}->{filter_name}/) { $self->{output}->output_add(long_msg => "skipping '" . $remote_peer . "': no matching filter peer name.", debug => 1); @@ -261,16 +286,7 @@ sub manage_selection { if ($mode->{type} eq 'ntpq') { my ($refid, $stratum, $type, $last_time, $polling_intervall, $reach, $delay, $offset, $jitter) = ($3, $4, $5, $6, $7, $8, $9, $10, $11); - $self->{peers}->{$remote_peer} = { - display => $remote_peer, - rawstate => $peer_fate, - state => $state_map_ntpq{$peer_fate}, - stratum => centreon::plugins::misc::trim($stratum), - rawtype => centreon::plugins::misc::trim($type), - type => $type_map_ntpq{centreon::plugins::misc::trim($type)}, - reach => centreon::plugins::misc::trim($reach), - offset => centreon::plugins::misc::trim($offset) - }; + $self->{peers}->{$remote_peer} = $entry; } elsif ($mode->{type} eq 'chronyc') { #210 Number of sources = 4 #MS Name/IP address Stratum Poll Reach LastRx Last sample @@ -278,19 +294,9 @@ sub manage_selection { #^+ 212.83.187.62 2 9 377 179 -715us[ -731us] +/- 50ms #^- 129.250.35.251 2 8 377 15 -82us[ -99us] +/- 96ms - my ($type, $stratum, $poll, $reach, $lastRX, $offset) = ($1, $4, $5, $6, $7, $9); - $self->{peers}->{$remote_peer} = { - display => $remote_peer, - rawstate => $peer_fate, - state => $state_map_chronyc{$peer_fate}, - stratum => centreon::plugins::misc::trim($stratum), - rawtype => centreon::plugins::misc::trim($type), - type => $type_map_chronyc{centreon::plugins::misc::trim($type)}, - reach => centreon::plugins::misc::trim($reach), - offset => centreon::plugins::misc::trim($offset) * $unit_map_chronyc{centreon::plugins::misc::trim($10)}, - }; + $self->{peers}->{$remote_peer} = $entry; } - + $self->{global}->{peers}++; } } From f2afd9f5d424501a75477302ddc4f0f731e90105 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 7 Mar 2023 15:37:09 +0000 Subject: [PATCH 347/447] (plugin) cloud::prometheus::restapi - mode expressions can use multiple instance option (#4262) --- src/cloud/prometheus/restapi/custom/api.pm | 11 +-- .../prometheus/restapi/mode/expression.pm | 95 +++++++++++-------- src/cloud/prometheus/restapi/plugin.pm | 13 ++- 3 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/cloud/prometheus/restapi/custom/api.pm b/src/cloud/prometheus/restapi/custom/api.pm index 58301c197..0f901ff3b 100644 --- a/src/cloud/prometheus/restapi/custom/api.pm +++ b/src/cloud/prometheus/restapi/custom/api.pm @@ -40,7 +40,7 @@ sub new { $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); $options{output}->option_exit(); } - + if (!defined($options{noptions})) { $options{options}->add_options(arguments => { 'hostname:s' => { name => 'hostname' }, @@ -117,19 +117,19 @@ sub settings { sub get_connection_info { my ($self, %options) = @_; - + return $self->{hostname} . ":" . $self->{port}; } sub get_hostname { my ($self, %options) = @_; - + return $self->{hostname}; } sub get_port { my ($self, %options) = @_; - + return $self->{port}; } @@ -168,9 +168,8 @@ sub get_endpoint { my ($self, %options) = @_; $self->settings(); - my $response = $self->{http}->request(url_path => $self->{url_path} . $options{url_path}); - + my $content; eval { $content = JSON::XS->new->utf8->decode($response); diff --git a/src/cloud/prometheus/restapi/mode/expression.pm b/src/cloud/prometheus/restapi/mode/expression.pm index 61c7c44af..9cc0ba889 100644 --- a/src/cloud/prometheus/restapi/mode/expression.pm +++ b/src/cloud/prometheus/restapi/mode/expression.pm @@ -24,17 +24,21 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_status_perfdata { my ($self, %options) = @_; - + + my $instances = []; + foreach (@{$self->{result_values}->{instances}}) { + push @$instances, $_->{value}; + } + foreach my $key (@{$self->{instance_mode}->{custom_keys}}) { $self->{output}->perfdata_add( - label => $key, nlabel => $key, value => $self->{result_values}->{$key}, - instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{instance} : undef + instances => $instances ); } } @@ -56,9 +60,14 @@ sub custom_status_output { sub custom_status_calc { my ($self, %options) = @_; - $self->{result_values}->{instance} = $options{new_datas}->{$self->{instance} . '_instance'}; + $self->{result_values}->{instances} = $options{new_datas}->{ $self->{instance} . '_instances' }; + $self->{result_values}->{instance} = $self->{result_values}->{instances}->[0]->{value}; # compatibility + foreach (@{$self->{result_values}->{instances}}) { + $self->{result_values}->{ $_->{name} } = $_->{value}; + } + foreach my $key (@{$self->{instance_mode}->{custom_keys}}) { - $self->{result_values}->{$key} = $options{new_datas}->{$self->{instance} . '_' . $key}; + $self->{result_values}->{$key} = $options{new_datas}->{ $self->{instance} . '_' . $key }; } return 0; @@ -66,38 +75,35 @@ sub custom_status_calc { sub set_counters { my ($self, %options) = @_; - + $self->{maps_counters_type} = [ - { name => 'expressions', type => 1, - message_multiple => 'All expressions results are ok', skipped_code => { -11 => 1 } }, + { name => 'expressions', type => 1, message_multiple => 'All expressions results are ok', skipped_code => { -11 => 1 } } ]; $self->{maps_counters}->{expressions} = [ - { label => 'status', set => { - key_values => [ { name => 'instance' } ], + { label => 'status', type => 2, set => { + key_values => [ { name => 'instances' } ], closure_custom_calc => $self->can('custom_status_calc'), closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => $self->can('custom_status_perfdata'), - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold_ng } - }, + } ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - + $options{options}->add_options(arguments => { - "query:s@" => { name => 'query' }, - "query-range:s@" => { name => 'query_range' }, - "instance:s" => { name => 'instance' }, - "aggregation:s" => { name => 'aggregation', default => 'average' }, - "output:s" => { name => 'output' }, - "multiple-output:s" => { name => 'multiple_output' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '' }, + 'query:s@' => { name => 'query' }, + 'query-range:s@' => { name => 'query_range' }, + 'instance:s@' => { name => 'instance' }, + 'aggregation:s' => { name => 'aggregation', default => 'average' }, + 'output:s' => { name => 'output' }, + 'multiple-output:s' => { name => 'multiple_output' } }); return $self; @@ -111,12 +117,20 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Need to specify output option."); $self->{output}->option_exit(); } - - if (!defined($self->{option_results}->{instance}) || $self->{option_results}->{instance} eq '') { + + $self->{instances} = []; + if (defined($self->{option_results}->{instance})) { + foreach (@{$self->{option_results}->{instance}}) { + next if ($_ eq ''); + push @{$self->{instances}}, $_; + } + } + + if (scalar(@{$self->{instances}}) <= 0) { $self->{output}->add_option_msg(short_msg => "Need to specify instance option."); $self->{output}->option_exit(); } - + if (!defined($self->{option_results}->{query}) && !defined($self->{option_results}->{query_range})) { $self->{output}->add_option_msg(short_msg => "Need to specify query or query-range option."); $self->{output}->option_exit(); @@ -127,7 +141,7 @@ sub check_options { foreach my $query (@{$self->{option_results}->{query}}) { next if ($query !~ /^(\w+),(.*)/); $self->{queries}->{$1} = $2; - push @{$self->{maps_counters}->{expressions}[0]->{set}->{key_values}}, { name => $1 }; + push @{$self->{maps_counters}->{expressions}->[0]->{set}->{key_values}}, { name => $1 }; push @{$self->{custom_keys}}, $1; } @@ -135,16 +149,14 @@ sub check_options { foreach my $query (@{$self->{option_results}->{query_range}}) { next if ($query !~ /^(\w+),(.*)/); $self->{query_ranges}->{$1} = $2; - push @{$self->{maps_counters}->{expressions}[0]->{set}->{key_values}}, { name => $1 }; + push @{$self->{maps_counters}->{expressions}->[0]->{set}->{key_values}}, { name => $1 }; push @{$self->{custom_keys}}, $1; } - $self->{maps_counters_type}[0]->{message_multiple} = $self->{option_results}->{multiple_output} if (defined($self->{option_results}->{multiple_output})); + $self->{maps_counters_type}->[0]->{message_multiple} = $self->{option_results}->{multiple_output} if (defined($self->{option_results}->{multiple_output})); $self->{prom_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; - $self->{prom_step} = defined($self->{option_results}->{step}) ? $self->{option_results}->{step} : "1m"; - - $self->change_macros(macros => ['warning_status', 'critical_status']); + $self->{prom_step} = defined($self->{option_results}->{step}) ? $self->{option_results}->{step} : '1m'; } sub manage_selection { @@ -162,19 +174,28 @@ sub manage_selection { push @query_ranges, $prom_query; } - my $queries_results = $options{custom}->query(queries => \@queries) if (scalar(@queries) > 0); my $query_ranges_results = $options{custom}->query_range(queries => \@query_ranges, timeframe => $self->{prom_timeframe}, step => $self->{prom_step}) if (scalar(@query_ranges) > 0); push @results, @{$queries_results} if (defined($queries_results)); push @results, @{$query_ranges_results} if (defined($query_ranges_results)); foreach my $result (@results) { - next if (!defined($result->{metric}->{$self->{option_results}->{instance}})); + my $instances = []; + foreach (@{$self->{instances}}) { + next if (!defined($result->{metric}->{$_})); + push @$instances, { name => $_, value => $result->{metric}->{$_} }; + } + + my $instance_key = join('_', @$instances); + next if (!defined($instance_key) || $instance_key eq ''); + my $value; $value = $options{custom}->compute(aggregation => $self->{option_results}->{aggregation}, values => $result->{values}) if (defined($result->{values})); - $value = ${$result->{value}}[1] if (defined($result->{value})); - $self->{expressions}->{$result->{metric}->{$self->{option_results}->{instance}}}->{instance} = $result->{metric}->{$self->{option_results}->{instance}}; - $self->{expressions}->{$result->{metric}->{$self->{option_results}->{instance}}}->{$result->{metric}->{__name__}} = $value; + $value = $result->{value}->[1] if (defined($result->{value})); + $self->{expressions}->{$instance_key} = { + instances => $instances, + $result->{metric}->{__name__} => $value + }; } if (scalar(keys %{$self->{expressions}}) <= 0) { diff --git a/src/cloud/prometheus/restapi/plugin.pm b/src/cloud/prometheus/restapi/plugin.pm index 852451eca..21c46442b 100644 --- a/src/cloud/prometheus/restapi/plugin.pm +++ b/src/cloud/prometheus/restapi/plugin.pm @@ -29,14 +29,13 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '0.1'; - %{$self->{modes}} = ( - 'discovery' => 'cloud::prometheus::restapi::mode::discovery', - 'expression' => 'cloud::prometheus::restapi::mode::expression', - 'target-status' => 'cloud::prometheus::restapi::mode::targetstatus', - ); + $self->{modes} = { + 'discovery' => 'cloud::prometheus::restapi::mode::discovery', + 'expression' => 'cloud::prometheus::restapi::mode::expression', + 'target-status' => 'cloud::prometheus::restapi::mode::targetstatus' + }; - $self->{custom_modes}{api} = 'cloud::prometheus::restapi::custom::api'; + $self->{custom_modes}->{api} = 'cloud::prometheus::restapi::custom::api'; return $self; } From 9c4e15e1f10bee35460df33a663ff38663605912 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Wed, 8 Mar 2023 10:35:39 +0100 Subject: [PATCH 348/447] fix(ci): detect properly plugin changes in lib directory (#4264) --- .github/scripts/process-plugins.py | 2 +- src/apps/protocols/dns/lib/dns.pm | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/process-plugins.py b/.github/scripts/process-plugins.py index 5a3fa8932..f4c80badb 100644 --- a/.github/scripts/process-plugins.py +++ b/.github/scripts/process-plugins.py @@ -31,7 +31,7 @@ list_packages = set() for plugin in plugins: list_plugins.add(plugin) try: - found = re.search('(.*)\/(?:plugin\.pm|mode\/.+|custom\/.+)', plugin).group(1) + found = re.search('(.*)\/(?:plugin\.pm|(?:lib|mode|custom)\/.+)', plugin).group(1) list_plugins.add(found) except AttributeError: pass diff --git a/src/apps/protocols/dns/lib/dns.pm b/src/apps/protocols/dns/lib/dns.pm index 126763013..d527e5756 100644 --- a/src/apps/protocols/dns/lib/dns.pm +++ b/src/apps/protocols/dns/lib/dns.pm @@ -49,7 +49,7 @@ sub search { $map_search_field->{PTR} = 'ptrdname' if (defined($self->{option_results}->{use_ptr_fqdn})); my $error_quit = defined($options{error_quit}) ? $options{error_quit} : undef; - + my $reply = $handle->search($self->{option_results}->{search}, $search_type); if ($reply) { foreach my $rr ($reply->answer) { @@ -68,14 +68,14 @@ sub search { $self->{output}->exit(); } } - + return sort @results; } sub connect { my ($self, %options) = @_; my %dns_options = (); - + if (defined($self->{option_results}->{nameservers})) { $dns_options{nameservers} = [@{$self->{option_results}->{nameservers}}]; } From 97570afbe35e5cbfaefc8252fe20bbcdba950b54 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 8 Mar 2023 10:06:58 +0000 Subject: [PATCH 349/447] (plugin) apps::controlm::restapi - new (#4266) --- .../deb.json | 5 + .../pkg.json | 9 + .../rpm.json | 5 + src/apps/controlm/restapi/custom/api.pm | 279 ++++++++++++++++ src/apps/controlm/restapi/mode/jobs.pm | 301 ++++++++++++++++++ src/apps/controlm/restapi/mode/listjobs.pm | 119 +++++++ src/apps/controlm/restapi/plugin.pm | 49 +++ 7 files changed, 767 insertions(+) create mode 100644 packaging/centreon-plugin-Applications-Controlm-Restapi/deb.json create mode 100644 packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json create mode 100644 packaging/centreon-plugin-Applications-Controlm-Restapi/rpm.json create mode 100644 src/apps/controlm/restapi/custom/api.pm create mode 100644 src/apps/controlm/restapi/mode/jobs.pm create mode 100644 src/apps/controlm/restapi/mode/listjobs.pm create mode 100644 src/apps/controlm/restapi/plugin.pm diff --git a/packaging/centreon-plugin-Applications-Controlm-Restapi/deb.json b/packaging/centreon-plugin-Applications-Controlm-Restapi/deb.json new file mode 100644 index 000000000..8133a85e5 --- /dev/null +++ b/packaging/centreon-plugin-Applications-Controlm-Restapi/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libdatetime-perl" + ] +} diff --git a/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json b/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json new file mode 100644 index 000000000..a1e55eede --- /dev/null +++ b/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json @@ -0,0 +1,9 @@ +{ + "pkg_name": "centreon-plugin-Applications-Contoolm-Restapi", + "pkg_summary": "Centreon Plugin to monitor Control-M throught Automation API", + "plugin_name": "centreon_controlm_restapi.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "apps/controlm/restapi/" + ] +} diff --git a/packaging/centreon-plugin-Applications-Controlm-Restapi/rpm.json b/packaging/centreon-plugin-Applications-Controlm-Restapi/rpm.json new file mode 100644 index 000000000..e9dff7552 --- /dev/null +++ b/packaging/centreon-plugin-Applications-Controlm-Restapi/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(DateTime)" + ] +} diff --git a/src/apps/controlm/restapi/custom/api.pm b/src/apps/controlm/restapi/custom/api.pm new file mode 100644 index 000000000..bdf2fce5c --- /dev/null +++ b/src/apps/controlm/restapi/custom/api.pm @@ -0,0 +1,279 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::controlm::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'api-username:s' => { name => 'api_username' }, + 'api-password:s' => { name => 'api_password' }, + 'hostname:s' => { name => 'hostname' }, + 'port:s' => { name => 'port' }, + 'proto:s' => { name => 'proto' }, + 'timeout:s' => { name => 'timeout' }, + 'unknown-http-status:s' => { name => 'unknown_http_status' }, + 'warning-http-status:s' => { name => 'warning_http_status' }, + 'critical-http-status:s' => { name => 'critical_http_status' } + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'AUTOMATION API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl'); + $self->{cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{option_results}->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8443; + $self->{option_results}->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{option_results}->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : ''; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; + $self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300'; + $self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : ''; + $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : ''; + + if ($self->{option_results}->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --hostname option.'); + $self->{output}->option_exit(); + } + if ($self->{api_username} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --api-username option.'); + $self->{output}->option_exit(); + } + if ($self->{api_password} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --api-password option.'); + $self->{output}->option_exit(); + } + + $self->{cache}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub settings { + my ($self, %options) = @_; + + return if (defined($self->{settings_done})); + $self->{http}->set_options(%{$self->{option_results}}); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{settings_done} = 1; +} + +sub get_connection_info { + my ($self, %options) = @_; + + return $self->{option_results}->{hostname} . ':' . $self->{option_results}->{port}; +} + +sub get_token { + my ($self, %options) = @_; + + my $has_cache_file = $self->{cache}->read(statefile => 'controlm_' . md5_hex($self->get_connection_info() . '_' . $self->{api_username})); + my $token = $self->{cache}->get(name => 'token'); + my $md5_secret_cache = $self->{cache}->get(name => 'md5_secret'); + my $md5_secret = md5_hex($self->{api_username} . $self->{api_password}); + + if ($has_cache_file == 0 || + !defined($token) || + (defined($md5_secret_cache) && $md5_secret_cache ne $md5_secret) + ) { + my $json_request = { + username => $self->{api_username}, + password => $self->{api_password} + }; + my $encoded; + eval { + $encoded = encode_json($json_request); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => 'cannot encode json request'); + $self->{output}->option_exit(); + } + + $self->settings(); + my $content = $self->{http}->request( + method => 'POST', + url_path => '/automation-api', + query_form_post => $encoded, + unknown_status => $self->{unknown_http_status}, + warning_status => $self->{warning_http_status}, + critical_status => $self->{critical_http_status}, + header => ['Content-Type: application/json'] + ); + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + + $token = $decoded->{token}; + my $datas = { + updated => time(), + token => $token, + md5_secret => $md5_secret + }; + $self->{cache}->write(data => $datas); + } + + return $token; +} + +sub clean_token { + my ($self, %options) = @_; + + my $datas = { updated => time() }; + $self->{cache}->write(data => $datas); +} + +sub request_api { + my ($self, %options) = @_; + + my $get_param = []; + if (defined($options{get_param})) { + $get_param = $options{get_param}; + } + push @$get_param, 'limit=10000'; + + $self->settings(); + my $token = $self->get_token(); + my ($content) = $self->{http}->request( + url_path => $options{endpoint}, + get_param => $get_param, + header => ['Authorization: Bearer ' . $token], + unknown_status => '', + warning_status => '', + critical_status => '' + ); + + # Maybe token is invalid. so we retry + if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { + $self->clean_token(); + $token = $self->get_token(); + $content = $self->{http}->request( + url_path => $options{endpoint}, + get_param => $get_param, + header => ['Authorization: Bearer ' . $token], + unknown_status => $self->{unknown_http_status}, + warning_status => $self->{warning_http_status}, + critical_status => $self->{critical_http_status} + ); + } + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->allow_nonref(1)->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +1; + +__END__ + +=head1 NAME + +Control-M Automation API + +=head1 AUTOMATION API OPTIONS + +Control-M API + +=over 8 + +=item B<--hostname> + +Set hostname. + +=item B<--port> + +Port used (Default: 8443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--api-username> + +API username. + +=item B<--api-password> + +API password. + +=item B<--timeout> + +Set timeout in seconds (Default: 30). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/src/apps/controlm/restapi/mode/jobs.pm b/src/apps/controlm/restapi/mode/jobs.pm new file mode 100644 index 000000000..58c9c5fdf --- /dev/null +++ b/src/apps/controlm/restapi/mode/jobs.pm @@ -0,0 +1,301 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::controlm::restapi::mode::jobs; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use Digest::MD5; +use DateTime; + +sub custom_status_output { + my ($self, %options) = @_; + + return 'status: ' . $self->{result_values}->{status}; +} + +sub custom_long_output { + my ($self, %options) = @_; + + return 'started since: ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{elapsed}); +} + +sub custom_failed_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => [$self->{result_values}->{application}, $self->{result_values}->{name}], + value => $self->{result_values}->{failed}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Number of jobs '; +} + +sub prefix_job_output { + my ($self, %options) = @_; + + return sprintf( + "job '%s/%s' ", + $options{instance_value}->{application}, + $options{instance_value}->{name} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', }, + { name => 'jobs', type => 1, cb_prefix_output => 'prefix_job_output', message_multiple => 'All jobs are ok', , skipped_code => { -10 => 1, -11 => 1 } } + ]; + + $self->{maps_counters}->{jobs} = [ + { + label => 'status', + type => 2, + critical_default => '%{status} =~ /ended not ok/i', + set => { + key_values => [ + { name => 'status' }, { name => 'name' }, { name => 'application' }, + { name => 'type' }, { name => 'folder' }, + ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'long', type => 2, set => { + key_values => [ + { name => 'status' }, { name => 'name' }, { name => 'application' }, + { name => 'type' }, { name => 'folder' }, { name => 'elapsed' } + ], + closure_custom_output => $self->can('custom_long_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'job-failed', nlabel => 'job.failed.count', display_ok => 0, set => { + key_values => [ + { name => 'failed' }, { name => 'name' }, { name => 'application' } + ], + output_template => 'failed: %s', + closure_custom_perfdata => $self->can('custom_failed_perfdata') + } + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'jobs-succeeded', nlabel => 'jobs.succeeded.count', set => { + key_values => [ { name => 'succeeded' }, { name => 'total' } ], + output_template => 'succeeded: %s', + perfdatas => [ + { template => '%s', min => 0, max => 'total' } + ] + } + }, + { label => 'jobs-failed', nlabel => 'jobs.failed.count', set => { + key_values => [ { name => 'failed' }, { name => 'total' } ], + output_template => 'errors: %s', + perfdatas => [ + { template => '%s', min => 0, max => 'total' } + ] + } + }, + { label => 'jobs-executing', nlabel => 'jobs.executing.count', set => { + key_values => [ { name => 'running' }, { name => 'total' } ], + output_template => 'executing: %s', + perfdatas => [ + { template => '%s', min => 0, max => 'total' } + ] + } + }, + { label => 'jobs-waiting', nlabel => 'jobs.waiting.count', set => { + key_values => [ { name => 'waiting' }, { name => 'total' } ], + output_template => 'waiting: %s', + perfdatas => [ + { template => '%s', min => 0, max => 'total' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-application:s' => { name => 'filter_application' }, + 'filter-folder:s' => { name => 'filter_folder' }, + 'filter-type:s' => { name => 'filter_type' }, + 'filter-name:s' => { name => 'filter_name' }, + 'timezone:s' => { name => 'timezone' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $jobs = $options{custom}->request_api( + endpoint => '/run/jobs/status', + get_param => ['jobname=*', 'application=*'] + ); + + my $current_time = time(); + $self->{global} = { total => 0, failed => 0, waiting => 0, succeeded => 0, executing => 0 }; + $self->{jobs} = {}; + foreach my $job (@{$jobs->{statuses}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $job->{name} !~ /$self->{option_results}->{filter_name}/); + next if (defined($self->{option_results}->{filter_folder}) && $self->{option_results}->{filter_folder} ne '' && + $job->{folder} !~ /$self->{option_results}->{filter_folder}/); + next if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $job->{type} !~ /$self->{option_results}->{filter_type}/); + next if (defined($self->{option_results}->{filter_application}) && $self->{option_results}->{filter_application} ne '' && + $job->{application} !~ /$self->{option_results}->{filter_application}/); + + my $elapsed; + # 20230214050004 + if ($job->{status} eq 'Executing' && $job->{startTime} =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/) { + my $tz = {}; + if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { + $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + } + my $dt = DateTime->new( + year => $1, + month => $2, + day => $3, + hour => $4, + minute => $5, + second => $6, + %$tz + ); + $elapsed = $current_time - $dt->epoch(); + } + + my $failed = 0; + $self->{global}->{total}++; + if ($job->{status} eq 'Executing' ) { + $self->{global}->{executing}++; + } elsif ($job->{status} =~ /Ended Not OK/i) { + $self->{global}->{failed}++; + $failed = 1; + } elsif ($job->{status} =~ /Ended OK/i) { + $self->{global}->{succeeded}++; + } elsif ($job->{status} =~ /Wait/i) { + # Wait User — waiting for user confirmation. + # Wait Resource — waiting on a resource to be available. + # Wait Host — waiting on an agent or remote host to be available. + # Wait Workload — waiting due to a workload limit. + # Wait Condition — waiting for a condition. + $self->{global}->{waiting}++; + } + $self->{jobs}->{ $job->{jobId} } = { + name => $job->{name}, + folder => $job->{folder}, + application => $job->{application}, + type => $job->{type}, + status => lc($job->{status}), + elapsed => $elapsed, + failed => 1 + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check jobs. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='failed' + +=item B<--filter-folder> + +Filter jobs by folder name (cannot be a regexp). + +=item B<--filter-application> + +Filter jobs by application name (cannot be a regexp). + +=item B<--filter-type> + +Filter jobs by type (cannot be a regexp). + +=item B<--filter-name> + +Filter jobs by job name (can be a regexp). + +=item B<--timezone> + +Set date timezone. +Can use format: 'Europe/London' or '+0100'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{name}, %{status}, %{application}, %{folder}, %{type} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /ended not ok/i'). +Can used special variables like: %{name}, %{status}, %{application}, %{folder}, %{type} + +=item B<--warning-long> + +Set warning threshold for long jobs. +Can used special variables like: %{name}, %{status}, %{elapsed}, %{application}, %{folder}, %{type} + +=item B<--critical-long> + +Set critical threshold for long jobs. +Can used special variables like: %{name}, %{status}, %{elapsed}, %{application}, %{folder}, %{type} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'jobs-succeeded', 'jobs-failed', 'jobs-executing', 'jobs-waiting', +'job-failed'. + +=back + +=cut diff --git a/src/apps/controlm/restapi/mode/listjobs.pm b/src/apps/controlm/restapi/mode/listjobs.pm new file mode 100644 index 000000000..d7ec48a03 --- /dev/null +++ b/src/apps/controlm/restapi/mode/listjobs.pm @@ -0,0 +1,119 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::controlm::restapi::mode::listjobs; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $jobs = $options{custom}->request_api( + endpoint => '/run/jobs/status', + get_param => ['jobname=*', 'application=*'] + ); + my $results = []; + foreach my $job (@{$jobs->{statuses}}) { + push @$results, { + name => $job->{name}, + type => $job->{type}, + folder => $job->{folder}, + application => $job->{application}, + ctm => $job->{ctm}, + status => lc($job->{status}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->output_add( + long_msg => sprintf( + '[name: %s][type: %s][folder: %s][application: %s][ctm: %s][status: %s]', + $_->{name}, + $_->{type}, + $_->{folder}, + $_->{application}, + $_->{ctm}, + $_->{status} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List jobs:' + ); + + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'type', 'folder', 'application', 'ctm', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->add_disco_entry(%$_); + } +} + +1; + +__END__ + +=head1 MODE + +List jobs. + +=over 8 + +=back + +=cut diff --git a/src/apps/controlm/restapi/plugin.pm b/src/apps/controlm/restapi/plugin.pm new file mode 100644 index 000000000..cff4a26dc --- /dev/null +++ b/src/apps/controlm/restapi/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::controlm::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'jobs' => 'apps::controlm::restapi::mode::jobs', + 'list-jobs' => 'apps::controlm::restapi::mode::listjobs' + }; + + $self->{custom_modes}->{api} = 'apps::controlm::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Control-M through Automation API. + +=cut From 200ffa659299d679d7667010b6b99eb729ee028e Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 8 Mar 2023 10:21:50 +0000 Subject: [PATCH 350/447] (plugin) os::linux::local - mode ntp fix offset threshold (#4267) --- src/os/linux/local/mode/ntp.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/os/linux/local/mode/ntp.pm b/src/os/linux/local/mode/ntp.pm index fbd2d9ec1..11a22df4c 100644 --- a/src/os/linux/local/mode/ntp.pm +++ b/src/os/linux/local/mode/ntp.pm @@ -82,7 +82,7 @@ sub custom_status_output { sub custom_offset_perfdata { my ($self, %options) = @_; - if ($self->{result_values}->{state} ne '*') { + if ($self->{result_values}->{rawstate} ne '*') { $self->{output}->perfdata_add( nlabel => $self->{nlabel}, unit => 'ms', @@ -106,7 +106,7 @@ sub custom_offset_perfdata { sub custom_offset_threshold { my ($self, %options) = @_; - if ($self->{result_values}->{state} ne '*') { + if ($self->{result_values}->{rawstate} ne '*') { return 'ok'; } return $self->{perfdata}->threshold_check(value => $self->{result_values}->{offset}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); @@ -150,7 +150,7 @@ sub set_counters { } }, { label => 'offset', nlabel => 'peer.time.offset.milliseconds', display_ok => 0, set => { - key_values => [ { name => 'offset' }, { name => 'state' }, { name => 'display' } ], + key_values => [ { name => 'offset' }, { name => 'rawstate' }, { name => 'display' } ], output_template => 'offset: %s ms', closure_custom_threshold_check => $self->can('custom_offset_threshold'), closure_custom_perfdata => $self->can('custom_offset_perfdata'), From b7d57998c58faa738e1e261111a5177f11535dce Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 8 Mar 2023 10:50:25 +0000 Subject: [PATCH 351/447] (plugin) apps::controlm::restapi - fix packaging (#4268) --- .../centreon-plugin-Applications-Controlm-Restapi/pkg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json b/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json index a1e55eede..c98c573a3 100644 --- a/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json +++ b/packaging/centreon-plugin-Applications-Controlm-Restapi/pkg.json @@ -1,5 +1,5 @@ { - "pkg_name": "centreon-plugin-Applications-Contoolm-Restapi", + "pkg_name": "centreon-plugin-Applications-Controlm-Restapi", "pkg_summary": "Centreon Plugin to monitor Control-M throught Automation API", "plugin_name": "centreon_controlm_restapi.pl", "files": [ From 4dc23401cc35acb6fb12433b838a2883435db793 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 8 Mar 2023 11:10:25 +0000 Subject: [PATCH 352/447] (plugin) apps::controlm::restapi - mode jobs fix perfdata (#4269) --- src/apps/controlm/restapi/mode/jobs.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/controlm/restapi/mode/jobs.pm b/src/apps/controlm/restapi/mode/jobs.pm index 58c9c5fdf..3c5c3216b 100644 --- a/src/apps/controlm/restapi/mode/jobs.pm +++ b/src/apps/controlm/restapi/mode/jobs.pm @@ -131,7 +131,7 @@ sub set_counters { } }, { label => 'jobs-executing', nlabel => 'jobs.executing.count', set => { - key_values => [ { name => 'running' }, { name => 'total' } ], + key_values => [ { name => 'executing' }, { name => 'total' } ], output_template => 'executing: %s', perfdatas => [ { template => '%s', min => 0, max => 'total' } @@ -229,7 +229,7 @@ sub manage_selection { type => $job->{type}, status => lc($job->{status}), elapsed => $elapsed, - failed => 1 + failed => $failed }; } } From a09d217fe829f11237f6e58ae0b10b8d59f10042 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 8 Mar 2023 16:44:39 +0000 Subject: [PATCH 353/447] (plugin) apps::controlm::restapi - fix login endpoint (#4270) --- src/apps/controlm/restapi/custom/api.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/controlm/restapi/custom/api.pm b/src/apps/controlm/restapi/custom/api.pm index bdf2fce5c..79c363703 100644 --- a/src/apps/controlm/restapi/custom/api.pm +++ b/src/apps/controlm/restapi/custom/api.pm @@ -145,7 +145,7 @@ sub get_token { $self->settings(); my $content = $self->{http}->request( method => 'POST', - url_path => '/automation-api', + url_path => '/session/login', query_form_post => $encoded, unknown_status => $self->{unknown_http_status}, warning_status => $self->{warning_http_status}, From 9ae8c43f9fef92ef1395b6d3a25d5a50319ac5fe Mon Sep 17 00:00:00 2001 From: qgarnier Date: Thu, 9 Mar 2023 08:31:44 +0000 Subject: [PATCH 354/447] (plugin) apps::controlm::restapi - fix endpoints (#4272) --- src/apps/controlm/restapi/custom/api.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/controlm/restapi/custom/api.pm b/src/apps/controlm/restapi/custom/api.pm index 79c363703..f4fd1f81f 100644 --- a/src/apps/controlm/restapi/custom/api.pm +++ b/src/apps/controlm/restapi/custom/api.pm @@ -145,7 +145,7 @@ sub get_token { $self->settings(); my $content = $self->{http}->request( method => 'POST', - url_path => '/session/login', + url_path => '/automation-api/session/login', query_form_post => $encoded, unknown_status => $self->{unknown_http_status}, warning_status => $self->{warning_http_status}, @@ -193,7 +193,7 @@ sub request_api { $self->settings(); my $token = $self->get_token(); my ($content) = $self->{http}->request( - url_path => $options{endpoint}, + url_path => '/automation-api' . $options{endpoint}, get_param => $get_param, header => ['Authorization: Bearer ' . $token], unknown_status => '', @@ -206,7 +206,7 @@ sub request_api { $self->clean_token(); $token = $self->get_token(); $content = $self->{http}->request( - url_path => $options{endpoint}, + url_path => '/automation-api' . $options{endpoint}, get_param => $get_param, header => ['Authorization: Bearer ' . $token], unknown_status => $self->{unknown_http_status}, From e9e6b1a788efa94660f2c6ae24ca3338d0b69ef1 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 10 Mar 2023 10:45:02 +0100 Subject: [PATCH 355/447] fix(ci): move connectors repo to plugins repo (#4273) --- .github/actions/deb-delivery/action.yml | 2 +- .github/actions/rpm-delivery/action.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/deb-delivery/action.yml b/.github/actions/deb-delivery/action.yml index 59bd779e5..4f9ff5dcc 100644 --- a/.github/actions/deb-delivery/action.yml +++ b/.github/actions/deb-delivery/action.yml @@ -42,7 +42,7 @@ runs: - name: Publish DEBs to artifactory run: | - jf rt upload "*.deb" "apt-connectors-${{ inputs.stability }}/pool/" --deb "${{ inputs.distrib }}/main/all" + jf rt upload "*.deb" "apt-plugins-${{ inputs.stability }}/pool/" --deb "${{ inputs.distrib }}/main/all" shell: bash - name: Publish DEBs to Nexus diff --git a/.github/actions/rpm-delivery/action.yml b/.github/actions/rpm-delivery/action.yml index a4d2dd614..f53e6a2ae 100644 --- a/.github/actions/rpm-delivery/action.yml +++ b/.github/actions/rpm-delivery/action.yml @@ -49,9 +49,9 @@ runs: JF_URL: https://centreon.jfrog.io JF_ACCESS_TOKEN: ${{ inputs.artifactory_token }} - - name: Publish RPMs to connectors repository + - name: Publish RPMs to plugins repository run: | - jf rt upload "*.rpm" "rpm-connectors/${{ inputs.distrib }}/${{ inputs.stability }}/noarch/" + jf rt upload "*.rpm" "rpm-plugins/${{ inputs.distrib }}/${{ inputs.stability }}/noarch/" shell: bash - name: Setup awscli From ec6537f9f5ab8f71e45026294c9015924e1a515b Mon Sep 17 00:00:00 2001 From: Laurent Pinsivy Date: Fri, 10 Mar 2023 11:07:51 +0100 Subject: [PATCH 356/447] enh(passwdmgr): Add Centreon Vault mode (#4254) --- .../plugins/passwordmgr/centreonvault.pm | 221 ++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 src/centreon/plugins/passwordmgr/centreonvault.pm diff --git a/src/centreon/plugins/passwordmgr/centreonvault.pm b/src/centreon/plugins/passwordmgr/centreonvault.pm new file mode 100644 index 000000000..c4ef4a530 --- /dev/null +++ b/src/centreon/plugins/passwordmgr/centreonvault.pm @@ -0,0 +1,221 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::plugins::passwordmgr::centreonvault; + +use strict; +use warnings; +use Data::Dumper; +use centreon::plugins::http; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class PasswordMgr: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class PasswordMgr: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + $options{options}->add_options(arguments => { + 'vault-config:s' => { name => 'vault_config', default => '/etc/centreon-engine/centreonvault.json'}, + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'VAULT OPTIONS'); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->new(%options, noptions => 1, default_backend => 'curl'); + + return $self; +} + +sub extract_map_options { + my ($self, %options) = @_; + + $self->{map_option} = []; + + # Parse all options to find '/\{.*\:\:secret\:\:(.*)\}/' dedicated patern in value and add entries in map_option + foreach my $option (keys %{$options{option_results}}) { + if (defined($options{option_results}{$option})) { + next if ($option eq 'map_option'); + if (ref($options{option_results}{$option}) eq 'ARRAY') { + foreach (@{$options{option_results}{$option}}) { + if ($_ =~ /\{.*\:\:secret\:\:(.*)\}/i) { + push (@{$self->{request_endpoint}}, "/v1".$1); + push (@{$self->{map_option}}, $option."=%".$_); + } + } + } else { + if ($options{option_results}{$option} =~ /\{.*\:\:secret\:\:(.*)\}/i) { + push (@{$self->{request_endpoint}}, "/v1".$1); + push (@{$self->{map_option}}, $option."=%".$options{option_results}{$option}); + } + } + } + } +} + +sub vault_settings { + my ($self, %options) = @_; + + if (!defined($options{option_results}->{vault_config}) + || $options{option_results}->{vault_config} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set --vault-config option"); + $self->{output}->option_exit(); + } + if (! -f $options{option_results}->{vault_config}) { + $self->{output}->add_option_msg(short_msg => "Cannot find file '$options{option_results}->{vault_config}'"); + $self->{output}->option_exit(); + } + + my $file_content = do { + local $/ = undef; + if (!open my $fh, "<", $options{option_results}->{vault_config}) { + $self->{output}->add_option_msg(short_msg => "Could not open file $options{option_results}->{vault_config}: $!"); + $self->{output}->option_exit(); + } + <$fh>; + }; + + my $json; + eval { + $json = JSON::XS->new->utf8->decode($file_content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json file"); + $self->{output}->option_exit(); + } + + foreach my $vault_name (keys %$json) { + $self->{$vault_name}->{vault_protocol} = 'https'; + $self->{$vault_name}->{vault_address} = '127.0.0.1'; + $self->{$vault_name}->{vault_port} = '8100'; + + $self->{$vault_name}->{vault_protocol} = $json->{$vault_name}->{'vault-protocol'} + if ($json->{$vault_name}->{'vault-protocol'} && $json->{$vault_name}->{'vault-protocol'} ne ''); + $self->{$vault_name}->{vault_address} = $json->{$vault_name}->{'vault-address'} + if ($json->{$vault_name}->{'vault-address'} && $json->{$vault_name}->{'vault-address'} ne ''); + $self->{$vault_name}->{vault_port} = $json->{$vault_name}->{'vault-port'} + if ($json->{$vault_name}->{'vault-port'} && $json->{$vault_name}->{'vault-port'} ne ''); + $self->{$vault_name}->{vault_token} = $json->{$vault_name}->{'vault-token'} + if ($json->{$vault_name}->{'vault-token'} && $json->{$vault_name}->{'vault-token'} ne ''); + } +} + +sub request_api { + my ($self, %options) = @_; + + $self->vault_settings(%options); + + $self->{lookup_values} = {}; + foreach my $endpoint (@{$self->{request_endpoint}}) { + # Extract vault name configuration from endpoint + my $vault_path = substr($endpoint, index($endpoint, '/', 1), length($endpoint)); + my $vault_name = substr($vault_path, 1, index($vault_path, '/', 1) - 1); + + my $headers = ['Accept: application/json']; + if (defined($self->{$vault_name}->{vault_token})) { + push @$headers, 'X-Vault-Token: ' . $self->{$vault_name}->{vault_token}; + } + + my ($response) = $self->{http}->request( + hostname => $self->{$vault_name}->{vault_address}, + port => $self->{$vault_name}->{vault_port}, + proto => $self->{$vault_name}->{vault_protocol}, + method => 'GET', + url_path => $endpoint, + header => $headers + ); + + my $json; + eval { + $json = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode Vault JSON response: $@"); + $self->{output}->option_exit(); + }; + + foreach (keys %{$json->{data}}) { + $self->{lookup_values}->{'{' . $_ . '::secret::' . substr($endpoint, index($endpoint, '/', 1)) . '}'} = $json->{data}->{$_}; + } + } +} + +sub do_map { + my ($self, %options) = @_; + + foreach (@{$self->{map_option}}) { + next if (! /^(.+?)=%(.+)$/); + + my ($option, $map) = ($1, $2); + + $map = $self->{lookup_values}->{$2} if (defined($self->{lookup_values}->{$2})); + $option =~ s/-/_/g; + $options{option_results}->{$option} = $map; + } + +} + +sub manage_options { + my ($self, %options) = @_; + + $self->extract_map_options(%options); + + return if (scalar(@{$self->{map_option}}) <= 0); + + $self->request_api(%options); + $self->do_map(%options); +} + +1; + +__END__ + +=head1 NAME + +Centreon Vault password manager + +=head1 SYNOPSIS + +Centreon Vault password manager + +To be used with an array containing keys/values saved in a secret path by resource + +=head1 VAULT OPTIONS + +=over 8 + +=item B<--vault-config> + +The path to the file defining access to the Centreon vault (/etc/centreon-engine/centreonvault.json by default) + +=back + +=head1 DESCRIPTION + +B. + +=cut From 8c86ef4c0dc00101c13a6c4d650d49309e217a1b Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 13 Mar 2023 10:51:58 +0000 Subject: [PATCH 357/447] (plugin) storage::netapp::ontap::restapi - mode hardware add disk component (#4278) --- .../ontap/restapi/mode/components/bay.pm | 7 +- .../ontap/restapi/mode/components/disk.pm | 68 +++++++++++++++++++ .../ontap/restapi/mode/components/fru.pm | 7 +- .../ontap/restapi/mode/components/shelf.pm | 7 +- .../netapp/ontap/restapi/mode/hardware.pm | 34 ++++++++-- 5 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 src/storage/netapp/ontap/restapi/mode/components/disk.pm diff --git a/src/storage/netapp/ontap/restapi/mode/components/bay.pm b/src/storage/netapp/ontap/restapi/mode/components/bay.pm index 19a50ac54..39b98c86c 100644 --- a/src/storage/netapp/ontap/restapi/mode/components/bay.pm +++ b/src/storage/netapp/ontap/restapi/mode/components/bay.pm @@ -31,9 +31,12 @@ sub check { $self->{output}->output_add(long_msg => 'checking bays'); $self->{components}->{bay} = { name => 'bays', total => 0, skip => 0 }; return if ($self->check_filter(section => 'bay')); - return if (!defined($self->{json_results}->{records})); - foreach my $shelf (@{$self->{json_results}->{records}}) { + $self->get_shelves(); + + return if (!defined($self->{shelves}->{records})); + + foreach my $shelf (@{$self->{shelves}->{records}}) { my $shelf_instance = $shelf->{serial_number}; my $shelf_name = $shelf->{name}; diff --git a/src/storage/netapp/ontap/restapi/mode/components/disk.pm b/src/storage/netapp/ontap/restapi/mode/components/disk.pm new file mode 100644 index 000000000..3e25c575a --- /dev/null +++ b/src/storage/netapp/ontap/restapi/mode/components/disk.pm @@ -0,0 +1,68 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::netapp::ontap::restapi::mode::components::disk; + +use strict; +use warnings; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => 'checking disks'); + $self->{components}->{disk} = { name => 'disks', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'disk')); + + my $disks = $self->get_disks(); + + return if (!defined($disks->{records})); + + foreach my $disk (@{$disks->{records}}) { + next if ($self->check_filter(section => 'disk', instance => $disk->{name})); + + $self->{components}->{disk}->{total}++; + $self->{output}->output_add( + long_msg => sprintf( + "disk '%s' state is '%s' [bay: %s, serial: %s, instance: %s]", + $disk->{name}, + $disk->{state}, + $disk->{bay}, + $disk->{serial_number}, + $disk->{name} + ) + ); + + my $exit = $self->get_severity(section => 'disk', value => $disk->{state}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf( + "Disk '%s' state is '%s'", + $disk->{name}, + $disk->{state} + ) + ); + } + } +} + +1; diff --git a/src/storage/netapp/ontap/restapi/mode/components/fru.pm b/src/storage/netapp/ontap/restapi/mode/components/fru.pm index 221bc7e16..61d8ea458 100644 --- a/src/storage/netapp/ontap/restapi/mode/components/fru.pm +++ b/src/storage/netapp/ontap/restapi/mode/components/fru.pm @@ -31,9 +31,12 @@ sub check { $self->{output}->output_add(long_msg => 'checking fru'); $self->{components}->{fru} = { name => 'frus', total => 0, skip => 0 }; return if ($self->check_filter(section => 'fru')); - return if (!defined($self->{json_results}->{records})); - foreach my $shelf (@{$self->{json_results}->{records}}) { + $self->get_shelves(); + + return if (!defined($self->{shelves}->{records})); + + foreach my $shelf (@{$self->{shelves}->{records}}) { my $shelf_instance = $shelf->{serial_number}; my $shelf_name = $shelf->{name}; diff --git a/src/storage/netapp/ontap/restapi/mode/components/shelf.pm b/src/storage/netapp/ontap/restapi/mode/components/shelf.pm index 216de56db..a4a1e5c5a 100644 --- a/src/storage/netapp/ontap/restapi/mode/components/shelf.pm +++ b/src/storage/netapp/ontap/restapi/mode/components/shelf.pm @@ -31,9 +31,12 @@ sub check { $self->{output}->output_add(long_msg => 'checking shelfs'); $self->{components}->{shelf} = { name => 'shelfs', total => 0, skip => 0 }; return if ($self->check_filter(section => 'shelf')); - return if (!defined($self->{json_results}->{records})); - foreach my $shelf (@{$self->{json_results}->{records}}) { + $self->get_shelves(); + + return if (!defined($self->{shelves}->{records})); + + foreach my $shelf (@{$self->{shelves}->{records}}) { my $shelf_instance = $shelf->{serial_number}; my $shelf_name = $shelf->{name}; diff --git a/src/storage/netapp/ontap/restapi/mode/hardware.pm b/src/storage/netapp/ontap/restapi/mode/hardware.pm index 31acf5145..1ee7589e0 100644 --- a/src/storage/netapp/ontap/restapi/mode/hardware.pm +++ b/src/storage/netapp/ontap/restapi/mode/hardware.pm @@ -28,18 +28,30 @@ use warnings; sub set_system { my ($self, %options) = @_; - $self->{cb_hook2} = 'execute_custom'; + $self->{cb_hook2} = 'save_custom'; $self->{thresholds} = { state => [ ['ok', 'OK'], ['error', 'CRITICAL'], ['.*', 'CRITICAL'] + ], + disk => [ + ['present', 'OK'], + ['broken', 'CRITICAL'], + ['copy', 'OK'], + ['maintenance', 'OK'], + ['partner', 'OK'], + ['reconstructing', 'OK'], + ['removed', 'OK'], + ['spare', 'OK'], + ['unfail', 'OK'], + ['zeroing', 'OK'] ] }; $self->{components_path} = 'storage::netapp::ontap::restapi::mode::components'; - $self->{components_module} = ['shelf', 'bay', 'fru']; + $self->{components_module} = ['bay', 'disk', 'fru', 'shelf']; } sub new { @@ -52,10 +64,24 @@ sub new { return $self; } -sub execute_custom { +sub get_disks { my ($self, %options) = @_; - $self->{json_results} = $options{custom}->request_api(endpoint => '/api/storage/shelves?fields=*'); + return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=*'); +} + +sub get_shelves { + my ($self, %options) = @_; + + return if (defined($self->{shelves})); + + $self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=*'); +} + +sub save_custom { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; } 1; From 9d9088647bcb9726f9b6a399773c7ae00802f709 Mon Sep 17 00:00:00 2001 From: sdepassio <114986849+sdepassio@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:03:48 +0100 Subject: [PATCH 358/447] (plugin) cloud::azure::policyinsights::policystates - new (#4224) --- .../deb.json | 4 + .../pkg.json | 10 ++ .../rpm.json | 4 + src/cloud/azure/custom/api.pm | 65 ++++++- .../policystates/mode/compliance.pm | 158 ++++++++++++++++++ .../policyinsights/policystates/plugin.pm | 57 +++++++ 6 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/deb.json create mode 100644 packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/pkg.json create mode 100644 packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/rpm.json create mode 100644 src/cloud/azure/policyinsights/policystates/mode/compliance.pm create mode 100644 src/cloud/azure/policyinsights/policystates/plugin.pm diff --git a/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/deb.json b/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/deb.json new file mode 100644 index 000000000..2a6bcc090 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/deb.json @@ -0,0 +1,4 @@ +{ + "dependencies": [ + ] +} \ No newline at end of file diff --git a/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/pkg.json b/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/pkg.json new file mode 100644 index 000000000..bd864f75b --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/pkg.json @@ -0,0 +1,10 @@ +{ + "pkg_name": "centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api", + "pkg_summary": "Centreon Plugin to monitor Microsoft Azure Policy States using RestAPI", + "plugin_name": "centreon_azure_policyinsights_policystates_api.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "cloud/azure/custom/", + "cloud/azure/policyinsights/policystates/" + ] +} \ No newline at end of file diff --git a/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/rpm.json b/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/rpm.json new file mode 100644 index 000000000..2a6bcc090 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Azure-PolicyInsights-PolicyStates-Api/rpm.json @@ -0,0 +1,4 @@ +{ + "dependencies": [ + ] +} \ No newline at end of file diff --git a/src/cloud/azure/custom/api.pm b/src/cloud/azure/custom/api.pm index 85f5f5137..f4e6a8dfc 100644 --- a/src/cloud/azure/custom/api.pm +++ b/src/cloud/azure/custom/api.pm @@ -150,8 +150,8 @@ sub get_access_token { my $has_cache_file = $options{statefile}->read( statefile => - 'azure_api_' . - md5_hex($self->{tenant}) . '_' . + 'azure_api_' . + md5_hex($self->{tenant}) . '_' . md5_hex($self->{client_id}) . '_' . md5_hex($self->{management_endpoint}) ); @@ -243,7 +243,7 @@ sub convert_duration { my ($self, %options) = @_; my $duration; - + if ($options{time_string} =~ /^P.*S$/) { centreon::plugins::misc::mymodule_load( output => $self->{output}, module => 'DateTime::Format::Duration::ISO8601', @@ -268,7 +268,7 @@ sub convert_duration { sub convert_iso8601_to_epoch { my ($self, %options) = @_; - + if ($options{time_string} =~ /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d.*)Z/) { my $dt = DateTime->new( year => $1, @@ -284,7 +284,7 @@ sub convert_iso8601_to_epoch { return $epoch_time; } - + $self->{output}->add_option_msg(short_msg => "Wrong date format: $options{time_string}"); $self->{output}->option_exit(); @@ -310,7 +310,7 @@ sub json_decode { sub azure_get_subscription_cost_management_set_url { my ($self, %options) = @_; - my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription} . "/providers/Microsoft.CostManagement/query?api-version=" . $self->{api_version} ; + my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription} . "/providers/Microsoft.CostManagement/query?api-version=" . $self->{api_version}; return $url; } @@ -321,7 +321,7 @@ sub azure_get_subscription_cost_management { my $results = {}; my $encoded_form_post; - my $full_url = $self->azure_get_subscription_cost_management_set_url(); + my $full_url = $self->azure_get_subscription_cost_management_set_url(); eval { $encoded_form_post = JSON::XS->new->utf8->encode($options{body_post}); @@ -1177,6 +1177,57 @@ sub azure_list_sqlelasticpools { return $full_response; } +sub azure_set_url { + my ($self, %options) = @_; + + my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription}; + $url .= "/resourceGroups/" . $options{resource_group} if length $options{resource_group}; + $url .= "/providers/" . $options{providers} if length $options{providers}; + $url .= "/" . $options{resource} if length $options{resource}; + $url .= "/" . $options{query_name}; +} + +sub azure_list_policystates { + my ($self, %options) = @_; + + my $get_params = [ + 'api-version', $self->{api_version}, + '$select', 'ResourceId, ResourceType, ResourceLocation, ResourceGroup, PolicyDefinitionName, IsCompliant, ComplianceState' + ]; + my $resource_location; + if (length $options{resource_location}) { + $resource_location = ("ResourceLocation eq '" . $options{resource_location} . "'"); + delete $options{$resource_location}; + } + my $resource_type; + if (length $options{resource_type}) { + $resource_type = ("ResourceType eq '" . $options{resource_type} . "'"); + delete $options{$resource_type}; + } + my $filter; + if (length $resource_location && length $resource_type) { + $filter = $resource_location . " and " . $resource_type; + } elsif (length $resource_location) { + $filter = $resource_location + } elsif (length $resource_type) { + $filter = $resource_type + } + if (length($filter)) { + push(@$get_params, '$filter', $filter); + } + + my ($url) = $self->azure_set_url(%options); + my $response = $self->request_api( + method => 'POST', + full_url => $url, + hostname => '', + header => ['Content-Type: application/json'], + get_params => $get_params + ); + + return $response->{value}; +} + 1; __END__ diff --git a/src/cloud/azure/policyinsights/policystates/mode/compliance.pm b/src/cloud/azure/policyinsights/policystates/mode/compliance.pm new file mode 100644 index 000000000..4c2838f44 --- /dev/null +++ b/src/cloud/azure/policyinsights/policystates/mode/compliance.pm @@ -0,0 +1,158 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::policyinsights::policystates::mode::compliance; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_compliance_state_output { + my ($self, %options) = @_; + return "Compliance state for policy '$self->{result_values}->{policy_name}' on resource '$self->{result_values}->{resource_name}' is '$self->{result_values}->{compliance_state}'"; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'non_compliant_policies', type => 0 }, + { name => 'compliance_state', type => 1, message_multiple => 'All compliances states are ok' } + ]; + + $self->{maps_counters}->{non_compliant_policies} = [ + { label => 'non-compliant-policies', nlabel => 'policies.non_compliant.count', set => { + key_values => [ { name => 'non_compliant_policies' } ], + output_template => 'Number of non compliant policies: %d', + perfdatas => [ + { label => 'total_non_compliant_policies', template => '%d', min => 0, unit => '' } + ] + } + } + ]; + + $self->{maps_counters}->{compliance_state} = [ + { label => 'compliance-state', + type => 2, + critical_default => '%{compliance_state} eq "NonCompliant"', + set => { + key_values => [ { name => 'compliance_state' }, { name => 'policy_name' }, { name => 'resource_name' }, { name => 'display' } ], + closure_custom_output => $self->can('custom_compliance_state_output'), + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'api-version:s' => { name => 'api_version', default => '2019-10-01'}, + 'policy-states:s' => { name => 'policy_states', default => 'default' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-location:s' => { name => 'resource_location' }, + 'resource-type:s' => { name => 'resource_type' } + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{policy_states} = (defined($self->{option_results}->{policy_states}) && $self->{option_results}->{policy_states} ne "") ? $self->{option_results}->{policy_states} : "default"; + $self->{api_version} = (defined($self->{option_results}->{api_version}) && $self->{option_results}->{api_version} ne "") ? $self->{option_results}->{api_version} : "2019-10-01"; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $policy_states = $options{custom}->azure_list_policystates( + providers => 'Microsoft.PolicyInsights/policyStates', + resource => $self->{policy_states}, + resource_group => $self->{option_results}->{resource_group}, + query_name => 'queryResults', + resource_location => $self->{option_results}->{resource_location}, + resource_type => $self->{option_results}->{resource_type} + ); + + my $non_compliant_policies = 0; + $self->{compliance_state} = {}; + foreach my $policy_state (@{ $policy_states }) { + my $resource_name = $policy_state->{resourceId}; + $resource_name =~ /.*\/(\w*)$/; + $resource_name = $1; + my $display = $policy_state->{policyDefinitionName} . "_" . $resource_name; + $self->{compliance_state}->{ $display } = { + display => $display, + compliance_state => $policy_state->{complianceState}, + policy_name => $policy_state->{policyDefinitionName}, + resource_name => $resource_name + }; + $non_compliant_policies = $non_compliant_policies + 1 if $policy_state->{complianceState} eq 'NonCompliant'; + }; + $self->{non_compliant_policies} = { non_compliant_policies => $non_compliant_policies }; +} + +1; + +__END__ + +=head1 MODE + +Check Azure policies compliance. + +Example: + +perl centreon_plugins.pl --plugin=cloud::azure::policyinsights::policystates::plugin --mode=compliance --policy-states=default +[--resource-group='MYRESOURCEGROUP'] --api-version=2019-10-01 + + +=over 8 + +=item B<--policy-states> + +The virtual resource under PolicyStates resource type. In a given time range, 'latest' represents the latest policy state(s), whereas 'default' represents all policy state(s). + +=item B<--resource-group> + +Set resource group (Optional). + +=item B<--resource-location> + +Set resource location (Optional). + +=item B<--resource-type> + +Set resource type (Optional). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'non-compliant-policies' ,'compliance-state'. + +=back + +=cut diff --git a/src/cloud/azure/policyinsights/policystates/plugin.pm b/src/cloud/azure/policyinsights/policystates/plugin.pm new file mode 100644 index 000000000..d8d4be0ff --- /dev/null +++ b/src/cloud/azure/policyinsights/policystates/plugin.pm @@ -0,0 +1,57 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::policyinsights::policystates::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'compliance' => 'cloud::azure::policyinsights::policystates::mode::compliance' + ); + + $self->{custom_modes}{api} = 'cloud::azure::custom::api'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->{options}->add_options(arguments => { }); + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure data factories. + +=cut From 7b11dcad59b7dc3b93f6fbcc85b62651cb250d76 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 14 Mar 2023 13:16:44 +0000 Subject: [PATCH 359/447] (plugin) network::hirschmann::standard::snmp - mode memory fix calc (#4280) --- .../hirschmann/standard/snmp/mode/memory.pm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/network/hirschmann/standard/snmp/mode/memory.pm b/src/network/hirschmann/standard/snmp/mode/memory.pm index a377f1f14..15ed9d534 100644 --- a/src/network/hirschmann/standard/snmp/mode/memory.pm +++ b/src/network/hirschmann/standard/snmp/mode/memory.pm @@ -88,12 +88,12 @@ my $map_enable = { my $mapping = { hios => { measure_enable => { oid => '.1.3.6.1.4.1.248.11.22.1.8.1', map => $map_enable }, # hm2DiagEnableMeasurement - ram_total => { oid => '.1.3.6.1.4.1.248.11.22.1.8.11.1' }, # hm2DiagMemoryRamAllocated + ram_used => { oid => '.1.3.6.1.4.1.248.11.22.1.8.11.1' }, # hm2DiagMemoryRamAllocated ram_free => { oid => '.1.3.6.1.4.1.248.11.22.1.8.11.2' } # hm2DiagMemoryRamFree }, classic => { measure_enable => { oid => '.1.3.6.1.4.1.248.14.2.15.1', map => $map_enable }, # hmEnableMeasurement - ram_total => { oid => '.1.3.6.1.4.1.248.14.2.15.3.1' }, # hmMemoryAllocated + ram_used => { oid => '.1.3.6.1.4.1.248.14.2.15.3.1' }, # hmMemoryAllocated ram_free => { oid => '.1.3.6.1.4.1.248.14.2.15.3.2' } # hmMemoryFree } }; @@ -109,14 +109,14 @@ sub check_memory { $self->{output}->option_exit(); } - $result->{ram_total} *= 1024; + $result->{ram_used} *= 1024; $result->{ram_free} *= 1024; $self->{ram} = { - total => $result->{ram_total}, - used => $result->{ram_total} - $result->{ram_free}, + total => $result->{ram_used} + $result->{ram_free}, + used => $result->{ram_used}, free => $result->{ram_free}, - prct_used => 100 - ($result->{ram_free} * 100 / $result->{ram_total}), - prct_free => $result->{ram_free} * 100 / $result->{ram_total} + prct_used => $result->{ram_used} * 100 / ($result->{ram_used} + $result->{ram_free}), + prct_free => $result->{ram_free} * 100 / ($result->{ram_used} + $result->{ram_free}) }; } From 031f24a945b63ce182fcd257670007300426b9f5 Mon Sep 17 00:00:00 2001 From: omercier <32134301+omercier@users.noreply.github.com> Date: Tue, 21 Mar 2023 23:15:34 +0100 Subject: [PATCH 360/447] Mon 17911 change curl delivery to nexus (#4291) * enh(deb-delivery): attempt to fiabilize delivery on nexus * enh(deb-delivery): more logical timeout options * test delivery * retrieve changes --------- Co-authored-by: Kevin Duret --- .github/actions/deb-delivery/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deb-delivery/action.yml b/.github/actions/deb-delivery/action.yml index 4f9ff5dcc..b5a6c12ed 100644 --- a/.github/actions/deb-delivery/action.yml +++ b/.github/actions/deb-delivery/action.yml @@ -55,6 +55,6 @@ runs: FOLDER_SUFFIX="" fi - find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 curl --fail -v -u "${{ inputs.nexus_username }}":"${{ inputs.nexus_password }}" -H "Content-Type: multipart/form-data" --data-binary "@%" https://apt.centreon.com/repository/$MAJOR$FOLDER_SUFFIX/ + find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 sh -c "curl --connect-timeout 10 --retry 2 --retry-max-time 30 --fail --silent --show-error -u '${{ inputs.nexus_username }}':'${{ inputs.nexus_password }}' -H 'Content-Type: multipart/form-data' --data-binary '@%' https://apt.centreon.com/repository/$MAJOR$FOLDER_SUFFIX/ >/dev/null || exit 255" || break done shell: bash From a79862fdc9f720de7b60687d21e9b23dd09fab11 Mon Sep 17 00:00:00 2001 From: Laurent Pinsivy Date: Thu, 23 Mar 2023 09:50:57 +0100 Subject: [PATCH 361/447] fix(centreonvault): fix endpoint extraction (#4292) --- .../plugins/passwordmgr/centreonvault.pm | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/centreon/plugins/passwordmgr/centreonvault.pm b/src/centreon/plugins/passwordmgr/centreonvault.pm index c4ef4a530..17d8cf1de 100644 --- a/src/centreon/plugins/passwordmgr/centreonvault.pm +++ b/src/centreon/plugins/passwordmgr/centreonvault.pm @@ -62,14 +62,14 @@ sub extract_map_options { next if ($option eq 'map_option'); if (ref($options{option_results}{$option}) eq 'ARRAY') { foreach (@{$options{option_results}{$option}}) { - if ($_ =~ /\{.*\:\:secret\:\:(.*)\}/i) { - push (@{$self->{request_endpoint}}, "/v1".$1); + if ($_ =~ /\{.*\:\:secret\:\:(.*)\:\:(.*)\}/i) { + push (@{$self->{request_endpoint}}, "$1::/v1/".$2); push (@{$self->{map_option}}, $option."=%".$_); } } } else { - if ($options{option_results}{$option} =~ /\{.*\:\:secret\:\:(.*)\}/i) { - push (@{$self->{request_endpoint}}, "/v1".$1); + if ($options{option_results}{$option} =~ /\{.*\:\:secret\:\:(.*)\:\:(.*)\}/i) { + push (@{$self->{request_endpoint}}, "$1::/v1/".$2); push (@{$self->{map_option}}, $option."=%".$options{option_results}{$option}); } } @@ -130,10 +130,19 @@ sub request_api { $self->vault_settings(%options); $self->{lookup_values} = {}; - foreach my $endpoint (@{$self->{request_endpoint}}) { + foreach my $item (@{$self->{request_endpoint}}) { # Extract vault name configuration from endpoint - my $vault_path = substr($endpoint, index($endpoint, '/', 1), length($endpoint)); - my $vault_name = substr($vault_path, 1, index($vault_path, '/', 1) - 1); + # 'vault::/v1//monitoring/hosts/7ad55afc-fa9e-4851-85b7-e26f47e421d7' + my ($vault_name, $endpoint); + if ($item =~ /(.*)\:\:(.*)/i) { + $vault_name = $1; + $endpoint = $2; + } + + if (!defined($self->{$vault_name})) { + $self->{output}->add_option_msg(short_msg => "Cannot get vault access for: $vault_name"); + $self->{output}->option_exit(); + } my $headers = ['Accept: application/json']; if (defined($self->{$vault_name}->{vault_token})) { @@ -159,7 +168,7 @@ sub request_api { }; foreach (keys %{$json->{data}}) { - $self->{lookup_values}->{'{' . $_ . '::secret::' . substr($endpoint, index($endpoint, '/', 1)) . '}'} = $json->{data}->{$_}; + $self->{lookup_values}->{'{' . $_ . '::secret::' . $vault_name . '::' . substr($endpoint, index($endpoint, '/', 1) + 1) . '}'} = $json->{data}->{$_}; } } } From 2df80388752019f948a6e0e8512aa217fa7a8ad3 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Thu, 23 Mar 2023 14:15:16 +0100 Subject: [PATCH 362/447] (plugin) database::mssql - mode loackswaits fix help (#4296) --- src/database/mssql/mode/lockswaits.pm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/database/mssql/mode/lockswaits.pm b/src/database/mssql/mode/lockswaits.pm index e4a47e66f..b9e806154 100644 --- a/src/database/mssql/mode/lockswaits.pm +++ b/src/database/mssql/mode/lockswaits.pm @@ -28,7 +28,7 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'lockswaits', type => 0 }, + { name => 'lockswaits', type => 0 } ]; $self->{maps_counters}->{lockswaits} = [ @@ -36,10 +36,10 @@ sub set_counters { key_values => [ { name => 'value' } ], output_template => '%.2f dead locks/s', perfdatas => [ - { template => '%.2f', min => 0 }, - ], + { template => '%.2f', min => 0 } + ] } - }, + } ]; } @@ -50,7 +50,7 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - "filter-database:s" => { name => 'filter_database' }, + 'filter-database:s' => { name => 'filter_database' } }); return $self; @@ -91,11 +91,11 @@ Check MSSQL locks-waits per second =over 8 -=item B<--warning-lockswait> +=item B<--warning-lockswaits> Threshold warning number of lock-waits per second. -=item B<--critical-lockswait> +=item B<--critical-lockswaits> Threshold critical number of lock-waits per second. From afbd9626fd14f5e1ced8b3d3b6b2710cf354edd8 Mon Sep 17 00:00:00 2001 From: THEPAUT Date: Thu, 23 Mar 2023 11:37:30 -0400 Subject: [PATCH 363/447] (plugin) os::windows::wsman - mode cpu fixes (#4300) --- src/os/windows/wsman/mode/cpu.pm | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/os/windows/wsman/mode/cpu.pm b/src/os/windows/wsman/mode/cpu.pm index 545a10a1d..45a8eddbb 100644 --- a/src/os/windows/wsman/mode/cpu.pm +++ b/src/os/windows/wsman/mode/cpu.pm @@ -38,13 +38,22 @@ sub custom_cpu_avg_calc { $skipped = 0; next if (!defined($options{old_datas}->{$_})); $buffer = 0; + if($options{old_datas}->{$prefix . '_PercentProcessorTime'} > $options{new_datas}->{$prefix . '_PercentProcessorTime'}) { + $options{old_datas}->{$prefix . '_PercentProcessorTime'} = 0; + } + if($options{old_datas}->{$prefix . '_Timestamp_Sys100NS'} > $options{new_datas}->{$prefix . '_Timestamp_Sys100NS'}) { + $options{old_datas}->{$prefix . '_Timestamp_Sys100NS'} = 0; + } - # - #Cal Method ref: http://technet.microsoft.com/en-us/library/cc757283%28WS.10%29.aspx - # - $total_cpu += (1 - ( $options{new_datas}->{$prefix . '_PercentProcessorTime'} - $options{old_datas}->{$prefix . '_PercentProcessorTime'} ) / - ( $options{new_datas}->{$prefix . '_Timestamp_Sys100NS'} - $options{old_datas}->{$prefix . '_Timestamp_Sys100NS'} ) ) * 100; - $count++; + # + #Cal Method ref: http://technet.microsoft.com/en-us/library/cc757283%28WS.10%29.aspx + # + my $cpu_core = (1 - ( $options{new_datas}->{$prefix . '_PercentProcessorTime'} - $options{old_datas}->{$prefix . '_PercentProcessorTime'} ) / + ( $options{new_datas}->{$prefix . '_Timestamp_Sys100NS'} - $options{old_datas}->{$prefix . '_Timestamp_Sys100NS'} ) ) * 100; + if ($cpu_core > 0) { + $total_cpu += $cpu_core; + } + $count++; } } @@ -68,6 +77,12 @@ sub custom_cpu_core_calc { my $core_usage = (1 - ( $options{new_datas}->{$self->{instance} . '_PercentProcessorTime'} - $options{old_datas}->{$self->{instance} . '_PercentProcessorTime'} ) / ( $options{new_datas}->{$self->{instance} . '_Timestamp_Sys100NS'} - $options{old_datas}->{$self->{instance} . '_Timestamp_Sys100NS'} ) ) * 100; $self->{result_values}->{prct_used} = $core_usage; + + if ($core_usage < 0) { + $self->{result_values}->{prct_used} = 0; + } else { + $self->{result_values}->{prct_used} = $core_usage; + } return 0; } From 543919b1dccb4c2d0fbdde0e02c11af2e1e236a5 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 24 Mar 2023 10:58:00 +0100 Subject: [PATCH 364/447] fix(delivery): restore release with timestamp/hash on unstable (#4302) --- .github/actions/deb-delivery/action.yml | 6 --- .github/actions/rpm-delivery/action.yml | 60 ++++++++++++++++--------- .github/workflows/plugin-delivery.yml | 13 +----- .github/workflows/plugins.yml | 2 - 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/.github/actions/deb-delivery/action.yml b/.github/actions/deb-delivery/action.yml index b5a6c12ed..892338fe7 100644 --- a/.github/actions/deb-delivery/action.yml +++ b/.github/actions/deb-delivery/action.yml @@ -10,12 +10,6 @@ inputs: nexus_password: description: The nexus password required: true - version: - description: "Centreon packaged version" - required: true - release: - description: The release number - required: true cache_key: description: "The cached package key" required: true diff --git a/.github/actions/rpm-delivery/action.yml b/.github/actions/rpm-delivery/action.yml index f53e6a2ae..fcddf4e84 100644 --- a/.github/actions/rpm-delivery/action.yml +++ b/.github/actions/rpm-delivery/action.yml @@ -1,15 +1,12 @@ name: "rpm-delivery" description: "rpm delivery" inputs: + module_name: + description: "The package module name" + required: true distrib: description: "The distribution used for packaging" required: true - version: - description: "Centreon packaged version" - required: true - release: - description: The release number - required: true cache_key: description: "The cached package key" required: true @@ -51,7 +48,41 @@ runs: - name: Publish RPMs to plugins repository run: | - jf rt upload "*.rpm" "rpm-plugins/${{ inputs.distrib }}/${{ inputs.stability }}/noarch/" + FILES="*.rpm" + + echo "[DEBUG] - Distrib: ${{ inputs.distrib }}" + + if [ -z "${{ inputs.module_name }}" ]; then + echo "module name is required" + exit 1 + fi + + if [ -z "${{ inputs.distrib }}" ]; then + echo "distrib is required" + exit 1 + fi + + mkdir noarch x86_64 + + for FILE in $FILES; do + echo "[DEBUG] - File: $FILE" + + ARCH=$(echo $FILE | grep -oP '(x86_64|noarch)') + + echo "[DEBUG] - Arch: $ARCH" + + cp "$FILE" "$ARCH" + done + + for ARCH in "noarch" "x86_64"; do + if [ "$(ls -A $ARCH)" ]; then + if [ "${{ inputs.stability }}" == "stable" ]; then + jf rt upload "$ARCH/*.rpm" "rpm-plugins/${{ inputs.distrib }}/${{ inputs.stability }}/$ARCH/" --flat + else + jf rt upload "$ARCH/*.rpm" "rpm-plugins/${{ inputs.distrib }}/${{ inputs.stability }}/$ARCH/${{ inputs.module_name }}/" --flat + fi + fi + done shell: bash - name: Setup awscli @@ -65,10 +96,7 @@ runs: run: | FILES="*.rpm" - VERSION="${{ inputs.version }}" - RELEASE="${{ inputs.release }}" REPOTYPE="${{ inputs.stability }}" - PROJECT="plugins" PROJECT_PATH="standard" DISTRIB="${{ inputs.distrib }}" ARCH="noarch" @@ -82,24 +110,16 @@ runs: if [ "$REPOTYPE" == "stable" ]; then TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/RPMS" else - FOLDER="centreon-$PROJECT-$VERSION-$RELEASE" - TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/$PROJECT/$FOLDER" - PROJECT_LOCATION="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/$PROJECT" + TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/${{ inputs.module_name }}" + PROJECT_LOCATION="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/${{ inputs.module_name }}" fi - echo "[DEBUG] - Folder: $FOLDER" - echo "[DEBUG] - Project : $PROJECT" echo "[DEBUG] - Target : $TARGET" echo "[DEBUG] - PROJECT_LOCATION : $PROJECT_LOCATION" ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" mkdir -p "$TARGET" scp -o StrictHostKeyChecking=no ./*.rpm "${{ inputs.yum_repo_address }}:$TARGET" - # Cleanup is done on unstable repository only - #if [ "$REPOTYPE" == "unstable" ]; then - # ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" "ls -drc $PROJECT_LOCATION/* 2>&- | head -n -1 | xargs rm -rf" - #fi - # Update repository metadata METADATAS="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH" ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" "sh "${{ inputs.update_repo_path }}" $METADATAS" 2>&- diff --git a/.github/workflows/plugin-delivery.yml b/.github/workflows/plugin-delivery.yml index 1263bf83c..b01065317 100644 --- a/.github/workflows/plugin-delivery.yml +++ b/.github/workflows/plugin-delivery.yml @@ -1,14 +1,6 @@ on: workflow_call: inputs: - version: - description: "Plugins version" - type: string - required: true - release: - description: The release number - type: string - required: true stability: description: The package stability (stable, testing, unstable) type: string @@ -48,9 +40,8 @@ jobs: - name: Delivery uses: ./.github/actions/rpm-delivery with: + module_name: plugins distrib: ${{ matrix.distrib }} - version: ${{ inputs.version }} - release: ${{ inputs.release }} cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} update_repo_path: ${{ secrets.update_repo_path }} cloudfront_id: ${{ secrets.cloudfront_id }} @@ -73,8 +64,6 @@ jobs: uses: ./.github/actions/deb-delivery with: distrib: ${{ matrix.distrib }} - version: ${{ inputs.version }} - release: ${{ inputs.release }} nexus_username: ${{ secrets.nexus_username }} nexus_password: ${{ secrets.nexus_password }} cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 741104e69..ca72b52c8 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -103,8 +103,6 @@ jobs: if: ${{ contains(fromJson('["stable", "testing", "unstable"]'), needs.get-environment.outputs.stability) }} uses: ./.github/workflows/plugin-delivery.yml with: - version: ${{ needs.get-environment.outputs.version }} - release: ${{ needs.get-environment.outputs.release }} stability: ${{ needs.get-environment.outputs.stability }} secrets: nexus_username: ${{ secrets.NEXUS_USERNAME }} From fe9c8b3118e4b49e5b27d29d1c56abe9dc17cbd4 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 27 Mar 2023 13:50:38 +0200 Subject: [PATCH 365/447] (plugin) apps::controlm::restapi - mode jobs add option --job-name (#4304) --- src/apps/controlm/restapi/mode/jobs.pm | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/apps/controlm/restapi/mode/jobs.pm b/src/apps/controlm/restapi/mode/jobs.pm index 3c5c3216b..be7957f48 100644 --- a/src/apps/controlm/restapi/mode/jobs.pm +++ b/src/apps/controlm/restapi/mode/jobs.pm @@ -72,12 +72,12 @@ sub prefix_job_output { sub set_counters { my ($self, %options) = @_; - + $self->{maps_counters_type} = [ { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', }, { name => 'jobs', type => 1, cb_prefix_output => 'prefix_job_output', message_multiple => 'All jobs are ok', , skipped_code => { -10 => 1, -11 => 1 } } ]; - + $self->{maps_counters}->{jobs} = [ { label => 'status', @@ -159,6 +159,7 @@ sub new { 'filter-folder:s' => { name => 'filter_folder' }, 'filter-type:s' => { name => 'filter_type' }, 'filter-name:s' => { name => 'filter_name' }, + 'job-name:s' => { name => 'job_name' }, 'timezone:s' => { name => 'timezone' } }); @@ -168,15 +169,23 @@ sub new { sub manage_selection { my ($self, %options) = @_; + my $get_param = ['application=*']; + if (defined($self->{option_results}->{job_name}) && $self->{option_results}->{job_name} ne '') { + push @$get_param, 'jobname=' . $self->{option_results}->{job_name}; + } else { + push @$get_param, 'jobname=*'; + } my $jobs = $options{custom}->request_api( endpoint => '/run/jobs/status', - get_param => ['jobname=*', 'application=*'] + get_param => $get_param ); my $current_time = time(); $self->{global} = { total => 0, failed => 0, waiting => 0, succeeded => 0, executing => 0 }; $self->{jobs} = {}; foreach my $job (@{$jobs->{statuses}}) { + next if (defined($self->{option_results}->{job_name}) && $self->{option_results}->{job_name} ne '' && + $job->{name} ne $self->{option_results}->{job_name}); next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $job->{name} !~ /$self->{option_results}->{filter_name}/); next if (defined($self->{option_results}->{filter_folder}) && $self->{option_results}->{filter_folder} ne '' && @@ -265,6 +274,10 @@ Filter jobs by type (cannot be a regexp). Filter jobs by job name (can be a regexp). +=item B<--job-name> + +Check exact job name (no regexp). + =item B<--timezone> Set date timezone. From 9b81c0c8d6729b758037660c5aecb0c24b0bfc43 Mon Sep 17 00:00:00 2001 From: itoussies <65223458+itoussies@users.noreply.github.com> Date: Mon, 27 Mar 2023 15:35:43 +0200 Subject: [PATCH 366/447] (plugin): cloud::aws::ec2::plugin - mode spot-active-instances small fix to code writing --- src/cloud/aws/ec2/mode/spotactiveinstances.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cloud/aws/ec2/mode/spotactiveinstances.pm b/src/cloud/aws/ec2/mode/spotactiveinstances.pm index aa03debc3..f1610035c 100644 --- a/src/cloud/aws/ec2/mode/spotactiveinstances.pm +++ b/src/cloud/aws/ec2/mode/spotactiveinstances.pm @@ -59,7 +59,7 @@ sub set_counters { ], } }, - ] + ]; } sub new { From a0e9c3fe0660036fe93a50cf363f0aa7f5131a9e Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 29 Mar 2023 11:44:17 +0200 Subject: [PATCH 367/447] (plugin) storage::netapp::ontap::restapi - mode hardware missing disk state (#4298) --- src/storage/netapp/ontap/restapi/mode/components/disk.pm | 3 +++ src/storage/netapp/ontap/restapi/mode/hardware.pm | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storage/netapp/ontap/restapi/mode/components/disk.pm b/src/storage/netapp/ontap/restapi/mode/components/disk.pm index 3e25c575a..dcaa6481a 100644 --- a/src/storage/netapp/ontap/restapi/mode/components/disk.pm +++ b/src/storage/netapp/ontap/restapi/mode/components/disk.pm @@ -39,6 +39,9 @@ sub check { foreach my $disk (@{$disks->{records}}) { next if ($self->check_filter(section => 'disk', instance => $disk->{name})); + # state can be missing + $disk->{state} = defined($disk->{state}) ? $disk->{state} : 'n/a'; + $self->{components}->{disk}->{total}++; $self->{output}->output_add( long_msg => sprintf( diff --git a/src/storage/netapp/ontap/restapi/mode/hardware.pm b/src/storage/netapp/ontap/restapi/mode/hardware.pm index 1ee7589e0..b0ef1d260 100644 --- a/src/storage/netapp/ontap/restapi/mode/hardware.pm +++ b/src/storage/netapp/ontap/restapi/mode/hardware.pm @@ -46,7 +46,8 @@ sub set_system { ['removed', 'OK'], ['spare', 'OK'], ['unfail', 'OK'], - ['zeroing', 'OK'] + ['zeroing', 'OK'], + ['n/a', 'OK'] ] }; From cb314fbc88f34871fca939c8ae6d0b92b9abf847 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 29 Mar 2023 11:44:25 +0200 Subject: [PATCH 368/447] (plugin) hardware::server::hp::ilo::restapi - mode hardware uninitialized value storage component (#4297) --- .../common/redfish/restapi/mode/components/storage.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/centreon/common/redfish/restapi/mode/components/storage.pm b/src/centreon/common/redfish/restapi/mode/components/storage.pm index f27bb50fe..33de68695 100644 --- a/src/centreon/common/redfish/restapi/mode/components/storage.pm +++ b/src/centreon/common/redfish/restapi/mode/components/storage.pm @@ -48,7 +48,7 @@ sub check { $self->{output}->output_add( long_msg => sprintf( "storage '%s/%s' status is '%s' [instance: %s, state: %s]", - $system_name, $storage_name, $storage->{Status}->{HealthRollup}, $instance, $storage->{Status}->{State} + $system_name, $storage_name, $storage->{Status}->{Health}, $instance, $storage->{Status}->{State} ) ); @@ -60,11 +60,11 @@ sub check { ); } - $exit = $self->get_severity(label => 'status', section => 'storage.status', value => $storage->{Status}->{HealthRollup}); + $exit = $self->get_severity(label => 'status', section => 'storage.status', value => $storage->{Status}->{Health}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, - short_msg => sprintf("Storage '%s/%s' status is '%s'", $system_name, $storage_name, $storage->{Status}->{HealthRollup}) + short_msg => sprintf("Storage '%s/%s' status is '%s'", $system_name, $storage_name, $storage->{Status}->{Health}) ); } } From feb9f8b67f55d9e5a40275afe4286da4f82dcd67 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 29 Mar 2023 17:03:24 +0200 Subject: [PATCH 369/447] (packaging) cloud::aws::cloudwatch - missing cloudfront discovery mode (#4320) --- packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json b/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json index 5f6f062b0..3da189d2c 100644 --- a/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json +++ b/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json @@ -8,6 +8,7 @@ "cloud/aws/cloudwatch/", "cloud/aws/apigateway/mode/discovery.pm", "cloud/aws/backup/mode/discovery.pm", + "cloud/aws/cloudfront/mode/discovery.pm", "cloud/aws/ebs/mode/discovery.pm", "cloud/aws/ec2/mode/discovery.pm", "cloud/aws/ec2/mode/discoveryspotfleetrequests.pm", From 103dd6524e9853d1cb621012c995e86dcb920cf4 Mon Sep 17 00:00:00 2001 From: alexvea <35368807+alexvea@users.noreply.github.com> Date: Wed, 29 Mar 2023 18:06:05 +0200 Subject: [PATCH 370/447] bulk modification for --unknown-status option description (#4321) --- .../backup/commvault/commserve/restapi/mode/storagepools.pm | 2 +- src/apps/microsoft/mscs/local/mode/networkstatus.pm | 2 +- src/apps/microsoft/mscs/local/mode/nodestatus.pm | 2 +- src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm | 2 +- src/apps/microsoft/mscs/local/mode/resourcestatus.pm | 2 +- src/apps/monitoring/mip/restapi/mode/scenarios.pm | 2 +- src/apps/vmware/connector/mode/countvmhost.pm | 2 +- src/apps/vmware/connector/mode/cpuhost.pm | 2 +- src/apps/vmware/connector/mode/cpuvm.pm | 2 +- src/apps/vmware/connector/mode/datastorecountvm.pm | 2 +- src/apps/vmware/connector/mode/datastorehost.pm | 2 +- src/apps/vmware/connector/mode/datastoreio.pm | 2 +- src/apps/vmware/connector/mode/datastoreiops.pm | 2 +- src/apps/vmware/connector/mode/datastoresnapshot.pm | 2 +- src/apps/vmware/connector/mode/datastoreusage.pm | 2 +- src/apps/vmware/connector/mode/datastorevm.pm | 2 +- src/apps/vmware/connector/mode/devicevm.pm | 2 +- src/apps/vmware/connector/mode/healthhost.pm | 2 +- src/apps/vmware/connector/mode/maintenancehost.pm | 2 +- src/apps/vmware/connector/mode/memoryhost.pm | 2 +- src/apps/vmware/connector/mode/memoryvm.pm | 2 +- src/apps/vmware/connector/mode/nethost.pm | 2 +- src/apps/vmware/connector/mode/netvm.pm | 2 +- src/apps/vmware/connector/mode/servicehost.pm | 2 +- src/apps/vmware/connector/mode/statuscluster.pm | 2 +- src/apps/vmware/connector/mode/statushost.pm | 2 +- src/apps/vmware/connector/mode/storagehost.pm | 2 +- src/apps/vmware/connector/mode/swaphost.pm | 2 +- src/apps/vmware/connector/mode/swapvm.pm | 2 +- src/apps/vmware/connector/mode/timehost.pm | 2 +- src/apps/vmware/connector/mode/uptimehost.pm | 2 +- src/centreon/common/bluearc/snmp/mode/clusterstatus.pm | 2 +- src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm | 2 +- src/centreon/common/cps/ups/snmp/mode/batterystatus.pm | 2 +- src/centreon/common/cps/ups/snmp/mode/inputlines.pm | 2 +- src/centreon/common/cps/ups/snmp/mode/outputlines.pm | 2 +- src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm | 2 +- src/database/informix/snmp/mode/chunkstatus.pm | 2 +- src/database/oracle/mode/asmdiskgroupusage.pm | 2 +- src/hardware/ats/eaton/snmp/mode/system.pm | 2 +- src/hardware/pdu/apc/snmp/mode/outlet.pm | 2 +- src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm | 2 +- src/hardware/server/hp/oneview/restapi/mode/storagepools.pm | 2 +- src/hardware/ups/alpha/snmp/mode/batterystatus.pm | 2 +- src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm | 2 +- src/network/cisco/standard/ssh/mode/voicedialpeer.pm | 2 +- src/network/juniper/common/junos/mode/ipsectunnel.pm | 2 +- src/os/linux/local/mode/traffic.pm | 2 +- src/storage/dell/equallogic/snmp/mode/diskusage.pm | 2 +- src/storage/emc/DataDomain/mode/replication.pm | 2 +- src/storage/emc/unisphere/restapi/mode/pools.pm | 2 +- src/storage/emc/unisphere/restapi/mode/storageresources.pm | 2 +- src/storage/netapp/ontap/snmp/mode/sis.pm | 2 +- src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm | 2 +- src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm | 2 +- src/storage/netapp/ontap/snmp/mode/volumeoptions.pm | 2 +- 56 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm b/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm index 3b1c5a657..383d054b6 100644 --- a/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm +++ b/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm @@ -166,7 +166,7 @@ Filter storage pools by name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status. +Set unknown threshold for status. Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/apps/microsoft/mscs/local/mode/networkstatus.pm b/src/apps/microsoft/mscs/local/mode/networkstatus.pm index d53ecbc5e..4a562e497 100644 --- a/src/apps/microsoft/mscs/local/mode/networkstatus.pm +++ b/src/apps/microsoft/mscs/local/mode/networkstatus.pm @@ -127,7 +127,7 @@ Filter interface name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Set unknown threshold for status (Default: '%{state} =~ /unknown/'). Can used special variables like: %{state}, %{display} =item B<--warning-status> diff --git a/src/apps/microsoft/mscs/local/mode/nodestatus.pm b/src/apps/microsoft/mscs/local/mode/nodestatus.pm index a6615ab39..60d416f96 100644 --- a/src/apps/microsoft/mscs/local/mode/nodestatus.pm +++ b/src/apps/microsoft/mscs/local/mode/nodestatus.pm @@ -126,7 +126,7 @@ Filter node name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Set unknown threshold for status (Default: '%{state} =~ /unknown/'). Can used special variables like: %{state}, %{display} =item B<--warning-status> diff --git a/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm b/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm index c58c63be5..e3aea281e 100644 --- a/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm +++ b/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm @@ -195,7 +195,7 @@ Filter resource group name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Set unknown threshold for status (Default: '%{state} =~ /unknown/'). Can used special variables like: %{state}, %{display}, %{owner_node} =item B<--warning-status> diff --git a/src/apps/microsoft/mscs/local/mode/resourcestatus.pm b/src/apps/microsoft/mscs/local/mode/resourcestatus.pm index 4397ea9cd..8870138cd 100644 --- a/src/apps/microsoft/mscs/local/mode/resourcestatus.pm +++ b/src/apps/microsoft/mscs/local/mode/resourcestatus.pm @@ -131,7 +131,7 @@ Filter resource name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Set unknown threshold for status (Default: '%{state} =~ /unknown/'). Can used special variables like: %{state}, %{display} =item B<--warning-status> diff --git a/src/apps/monitoring/mip/restapi/mode/scenarios.pm b/src/apps/monitoring/mip/restapi/mode/scenarios.pm index 03fb6c3dd..8c4daf5ed 100644 --- a/src/apps/monitoring/mip/restapi/mode/scenarios.pm +++ b/src/apps/monitoring/mip/restapi/mode/scenarios.pm @@ -330,7 +330,7 @@ Only check new result entries for scenarios. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/countvmhost.pm b/src/apps/vmware/connector/mode/countvmhost.pm index 5ada4a023..f3ab006e8 100644 --- a/src/apps/vmware/connector/mode/countvmhost.pm +++ b/src/apps/vmware/connector/mode/countvmhost.pm @@ -190,7 +190,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/cpuhost.pm b/src/apps/vmware/connector/mode/cpuhost.pm index 7a7865d92..685160e1c 100644 --- a/src/apps/vmware/connector/mode/cpuhost.pm +++ b/src/apps/vmware/connector/mode/cpuhost.pm @@ -196,7 +196,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/cpuvm.pm b/src/apps/vmware/connector/mode/cpuvm.pm index fc34a89d0..f3d9a9b5a 100644 --- a/src/apps/vmware/connector/mode/cpuvm.pm +++ b/src/apps/vmware/connector/mode/cpuvm.pm @@ -232,7 +232,7 @@ Search in following host(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). +Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). Can used special variables like: %{connection_state}, %{power_state} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastorecountvm.pm b/src/apps/vmware/connector/mode/datastorecountvm.pm index 8227bd95d..ee08ef0e2 100644 --- a/src/apps/vmware/connector/mode/datastorecountvm.pm +++ b/src/apps/vmware/connector/mode/datastorecountvm.pm @@ -183,7 +183,7 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i'). +Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). Can used special variables like: %{accessible} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastorehost.pm b/src/apps/vmware/connector/mode/datastorehost.pm index 8ca79e682..4c3802a46 100644 --- a/src/apps/vmware/connector/mode/datastorehost.pm +++ b/src/apps/vmware/connector/mode/datastorehost.pm @@ -188,7 +188,7 @@ Datastore name is a regexp. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastoreio.pm b/src/apps/vmware/connector/mode/datastoreio.pm index 554e54196..2225cfb55 100644 --- a/src/apps/vmware/connector/mode/datastoreio.pm +++ b/src/apps/vmware/connector/mode/datastoreio.pm @@ -163,7 +163,7 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i'). +Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). Can used special variables like: %{accessible} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastoreiops.pm b/src/apps/vmware/connector/mode/datastoreiops.pm index 9802ce1bf..8634a9400 100644 --- a/src/apps/vmware/connector/mode/datastoreiops.pm +++ b/src/apps/vmware/connector/mode/datastoreiops.pm @@ -241,7 +241,7 @@ Only display VMs with iops higher value (default: 50). =item B<--unknown-status> -Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i'). +Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). Can used special variables like: %{accessible} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastoresnapshot.pm b/src/apps/vmware/connector/mode/datastoresnapshot.pm index 0946486b4..0a61bc4b4 100644 --- a/src/apps/vmware/connector/mode/datastoresnapshot.pm +++ b/src/apps/vmware/connector/mode/datastoresnapshot.pm @@ -172,7 +172,7 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i'). +Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). Can used special variables like: %{accessible} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastoreusage.pm b/src/apps/vmware/connector/mode/datastoreusage.pm index 840a93095..e87e3da76 100644 --- a/src/apps/vmware/connector/mode/datastoreusage.pm +++ b/src/apps/vmware/connector/mode/datastoreusage.pm @@ -266,7 +266,7 @@ Explicitly ask vmware to refreshes free-space and capacity values (slower). =item B<--unknown-status> -Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i'). +Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). Can used special variables like: %{accessible} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/datastorevm.pm b/src/apps/vmware/connector/mode/datastorevm.pm index 1f04153f8..a817cda3b 100644 --- a/src/apps/vmware/connector/mode/datastorevm.pm +++ b/src/apps/vmware/connector/mode/datastorevm.pm @@ -242,7 +242,7 @@ Display virtual machine description. =item B<--unknown-status> -Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). +Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). Can used special variables like: %{connection_state}, %{power_state} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/devicevm.pm b/src/apps/vmware/connector/mode/devicevm.pm index d7e070e7e..49bae3e45 100644 --- a/src/apps/vmware/connector/mode/devicevm.pm +++ b/src/apps/vmware/connector/mode/devicevm.pm @@ -199,7 +199,7 @@ Device to check (Required) (Example: --device='VirtualCdrom'). =item B<--unknown-status> -Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i'). Can used special variables like: %{connection_state} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/healthhost.pm b/src/apps/vmware/connector/mode/healthhost.pm index 28607ad33..48b50164f 100644 --- a/src/apps/vmware/connector/mode/healthhost.pm +++ b/src/apps/vmware/connector/mode/healthhost.pm @@ -328,7 +328,7 @@ Check storage(s) status. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/maintenancehost.pm b/src/apps/vmware/connector/mode/maintenancehost.pm index f15f9b873..7c8dd4a53 100644 --- a/src/apps/vmware/connector/mode/maintenancehost.pm +++ b/src/apps/vmware/connector/mode/maintenancehost.pm @@ -144,7 +144,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/memoryhost.pm b/src/apps/vmware/connector/mode/memoryhost.pm index 5c4680558..549379a22 100644 --- a/src/apps/vmware/connector/mode/memoryhost.pm +++ b/src/apps/vmware/connector/mode/memoryhost.pm @@ -261,7 +261,7 @@ Thresholds are on free space left. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/memoryvm.pm b/src/apps/vmware/connector/mode/memoryvm.pm index 65cc7c100..cf9eef31b 100644 --- a/src/apps/vmware/connector/mode/memoryvm.pm +++ b/src/apps/vmware/connector/mode/memoryvm.pm @@ -339,7 +339,7 @@ Display virtual machine description. =item B<--unknown-status> -Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). +Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). Can used special variables like: %{connection_state}, %{power_state} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/nethost.pm b/src/apps/vmware/connector/mode/nethost.pm index 6496e01c7..3068f8711 100644 --- a/src/apps/vmware/connector/mode/nethost.pm +++ b/src/apps/vmware/connector/mode/nethost.pm @@ -390,7 +390,7 @@ It monitors only ESX nic that belongs to the filtered vswitches. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/netvm.pm b/src/apps/vmware/connector/mode/netvm.pm index 239c039bc..ec13c9d7a 100644 --- a/src/apps/vmware/connector/mode/netvm.pm +++ b/src/apps/vmware/connector/mode/netvm.pm @@ -322,7 +322,7 @@ Display virtual machine description. =item B<--unknown-status> -Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). +Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). Can used special variables like: %{connection_state}, %{power_state} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/servicehost.pm b/src/apps/vmware/connector/mode/servicehost.pm index 8e9749b3a..5da125bee 100644 --- a/src/apps/vmware/connector/mode/servicehost.pm +++ b/src/apps/vmware/connector/mode/servicehost.pm @@ -179,7 +179,7 @@ Filter services you want to check (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/statuscluster.pm b/src/apps/vmware/connector/mode/statuscluster.pm index 40b4b292f..4963760b3 100644 --- a/src/apps/vmware/connector/mode/statuscluster.pm +++ b/src/apps/vmware/connector/mode/statuscluster.pm @@ -131,7 +131,7 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{overall_status} =~ /gray/i || %{vsan_status} =~ /gray/i'). +Set unknown threshold for status (Default: '%{overall_status} =~ /gray/i || %{vsan_status} =~ /gray/i'). Can used special variables like: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/statushost.pm b/src/apps/vmware/connector/mode/statushost.pm index 128da4abb..fa51c18f1 100644 --- a/src/apps/vmware/connector/mode/statushost.pm +++ b/src/apps/vmware/connector/mode/statushost.pm @@ -147,7 +147,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/storagehost.pm b/src/apps/vmware/connector/mode/storagehost.pm index d55a743af..d419ea5a0 100644 --- a/src/apps/vmware/connector/mode/storagehost.pm +++ b/src/apps/vmware/connector/mode/storagehost.pm @@ -360,7 +360,7 @@ Filter paths by name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i'). Can used special variables like: %{status}, %{maintenance} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/swaphost.pm b/src/apps/vmware/connector/mode/swaphost.pm index 1c00d9886..365065789 100644 --- a/src/apps/vmware/connector/mode/swaphost.pm +++ b/src/apps/vmware/connector/mode/swaphost.pm @@ -150,7 +150,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/swapvm.pm b/src/apps/vmware/connector/mode/swapvm.pm index 3f3d548c3..00852aaa3 100644 --- a/src/apps/vmware/connector/mode/swapvm.pm +++ b/src/apps/vmware/connector/mode/swapvm.pm @@ -175,7 +175,7 @@ Display virtual machine description. =item B<--unknown-status> -Set warning threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). +Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). Can used special variables like: %{connection_state}, %{power_state} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/timehost.pm b/src/apps/vmware/connector/mode/timehost.pm index 63169f673..132319fca 100644 --- a/src/apps/vmware/connector/mode/timehost.pm +++ b/src/apps/vmware/connector/mode/timehost.pm @@ -156,7 +156,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/apps/vmware/connector/mode/uptimehost.pm b/src/apps/vmware/connector/mode/uptimehost.pm index 7dcfc3364..bcc011394 100644 --- a/src/apps/vmware/connector/mode/uptimehost.pm +++ b/src/apps/vmware/connector/mode/uptimehost.pm @@ -156,7 +156,7 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). +Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm b/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm index baaa407fa..3acd57864 100644 --- a/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm +++ b/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm @@ -130,7 +130,7 @@ Filter node name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{state} =~ /unknown/'). +Set unknown threshold for status (Default: '%{state} =~ /unknown/'). Can used special variables like: %{state}, %{display} =item B<--warning-status> diff --git a/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm b/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm index 2db71861b..4aa0a00e6 100644 --- a/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm +++ b/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm @@ -251,7 +251,7 @@ Check email security usage. =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{queue_status}, %{resource_conservation} =item B<--warning-status> diff --git a/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm b/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm index 3e5dee7e8..832586cd1 100644 --- a/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm +++ b/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm @@ -143,7 +143,7 @@ Check battery status and charge remaining. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown|notPresent/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown|notPresent/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/centreon/common/cps/ups/snmp/mode/inputlines.pm b/src/centreon/common/cps/ups/snmp/mode/inputlines.pm index 15f42c4d0..d47985305 100644 --- a/src/centreon/common/cps/ups/snmp/mode/inputlines.pm +++ b/src/centreon/common/cps/ups/snmp/mode/inputlines.pm @@ -131,7 +131,7 @@ Check INPUT lines metrics. =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/centreon/common/cps/ups/snmp/mode/outputlines.pm b/src/centreon/common/cps/ups/snmp/mode/outputlines.pm index 47fd6adb6..efd27c2d9 100644 --- a/src/centreon/common/cps/ups/snmp/mode/outputlines.pm +++ b/src/centreon/common/cps/ups/snmp/mode/outputlines.pm @@ -165,7 +165,7 @@ Check output lines metrics. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm b/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm index ea8ebaab1..9be386ab9 100644 --- a/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm +++ b/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm @@ -238,7 +238,7 @@ Filter by access point name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{admin}, %{status}, %{display} =item B<--warning-status> diff --git a/src/database/informix/snmp/mode/chunkstatus.pm b/src/database/informix/snmp/mode/chunkstatus.pm index 9ab56d2ce..39440a730 100644 --- a/src/database/informix/snmp/mode/chunkstatus.pm +++ b/src/database/informix/snmp/mode/chunkstatus.pm @@ -157,7 +157,7 @@ Filter chunk name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/database/oracle/mode/asmdiskgroupusage.pm b/src/database/oracle/mode/asmdiskgroupusage.pm index 3f91f58eb..87089141b 100644 --- a/src/database/oracle/mode/asmdiskgroupusage.pm +++ b/src/database/oracle/mode/asmdiskgroupusage.pm @@ -265,7 +265,7 @@ Threshold critical. =item B<--unknown-status> -Set warning threshold for status. +Set unknown threshold for status. Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/hardware/ats/eaton/snmp/mode/system.pm b/src/hardware/ats/eaton/snmp/mode/system.pm index 08ae6581e..ca9b7af72 100644 --- a/src/hardware/ats/eaton/snmp/mode/system.pm +++ b/src/hardware/ats/eaton/snmp/mode/system.pm @@ -164,7 +164,7 @@ Example: --filter-counters='^status$' =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: operation_mode =item B<--warning-status> diff --git a/src/hardware/pdu/apc/snmp/mode/outlet.pm b/src/hardware/pdu/apc/snmp/mode/outlet.pm index 48f98f294..bb4b88c1b 100644 --- a/src/hardware/pdu/apc/snmp/mode/outlet.pm +++ b/src/hardware/pdu/apc/snmp/mode/outlet.pm @@ -244,7 +244,7 @@ Check outlet. =item B<--unknown-status> -Set warning threshold for status. +Set unknown threshold for status. Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm b/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm index 15d13c43f..bc87ee19d 100644 --- a/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm +++ b/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm @@ -171,7 +171,7 @@ Check the overall status of iDrac card. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm b/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm index c81045a9f..1e9961ce3 100644 --- a/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm +++ b/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm @@ -172,7 +172,7 @@ Filter pool name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/hardware/ups/alpha/snmp/mode/batterystatus.pm b/src/hardware/ups/alpha/snmp/mode/batterystatus.pm index 0b2919cf5..566e2bc39 100644 --- a/src/hardware/ups/alpha/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/alpha/snmp/mode/batterystatus.pm @@ -160,7 +160,7 @@ Example: --filter-counters='^status|load$' =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm index 13657a760..227b178a2 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm @@ -162,7 +162,7 @@ Check battery status and charge remaining. =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status} =item B<--warning-status> diff --git a/src/network/cisco/standard/ssh/mode/voicedialpeer.pm b/src/network/cisco/standard/ssh/mode/voicedialpeer.pm index 5c0932793..48d2caea2 100644 --- a/src/network/cisco/standard/ssh/mode/voicedialpeer.pm +++ b/src/network/cisco/standard/ssh/mode/voicedialpeer.pm @@ -163,7 +163,7 @@ Filter name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{admin}, %{oper}, %{keepalive}, %{display} =item B<--warning-status> diff --git a/src/network/juniper/common/junos/mode/ipsectunnel.pm b/src/network/juniper/common/junos/mode/ipsectunnel.pm index f39084f00..1faaab6c8 100644 --- a/src/network/juniper/common/junos/mode/ipsectunnel.pm +++ b/src/network/juniper/common/junos/mode/ipsectunnel.pm @@ -248,7 +248,7 @@ Example: --filter-counters='tunnels-total' =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{ike_state}, %{display} =item B<--warning-status> diff --git a/src/os/linux/local/mode/traffic.pm b/src/os/linux/local/mode/traffic.pm index 233a098b5..dac33da63 100644 --- a/src/os/linux/local/mode/traffic.pm +++ b/src/os/linux/local/mode/traffic.pm @@ -305,7 +305,7 @@ Threshold critical in percent for 'out' traffic. =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/storage/dell/equallogic/snmp/mode/diskusage.pm b/src/storage/dell/equallogic/snmp/mode/diskusage.pm index d43dcd98f..c1a8a66dd 100644 --- a/src/storage/dell/equallogic/snmp/mode/diskusage.pm +++ b/src/storage/dell/equallogic/snmp/mode/diskusage.pm @@ -191,7 +191,7 @@ Filter disk name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{health}, %{status}, %{display} =item B<--warning-status> diff --git a/src/storage/emc/DataDomain/mode/replication.pm b/src/storage/emc/DataDomain/mode/replication.pm index ba19e888f..ba5690004 100644 --- a/src/storage/emc/DataDomain/mode/replication.pm +++ b/src/storage/emc/DataDomain/mode/replication.pm @@ -160,7 +160,7 @@ Example: --filter-counters='^status$' =item B<--unknown-status> -Set warning threshold for status (Default: none). +Set unknown threshold for status (Default: none). Can used special variables like: %{state} =item B<--warning-status> diff --git a/src/storage/emc/unisphere/restapi/mode/pools.pm b/src/storage/emc/unisphere/restapi/mode/pools.pm index b203771e8..fb302d404 100644 --- a/src/storage/emc/unisphere/restapi/mode/pools.pm +++ b/src/storage/emc/unisphere/restapi/mode/pools.pm @@ -207,7 +207,7 @@ Filter pool name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/storage/emc/unisphere/restapi/mode/storageresources.pm b/src/storage/emc/unisphere/restapi/mode/storageresources.pm index 3077beceb..f7570be36 100644 --- a/src/storage/emc/unisphere/restapi/mode/storageresources.pm +++ b/src/storage/emc/unisphere/restapi/mode/storageresources.pm @@ -210,7 +210,7 @@ Filter name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). Can used special variables like: %{status}, %{display} =item B<--warning-status> diff --git a/src/storage/netapp/ontap/snmp/mode/sis.pm b/src/storage/netapp/ontap/snmp/mode/sis.pm index 7d7803e9d..debf7cd34 100644 --- a/src/storage/netapp/ontap/snmp/mode/sis.pm +++ b/src/storage/netapp/ontap/snmp/mode/sis.pm @@ -174,7 +174,7 @@ Filter name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{state}, %{status}, %{lastOpError}, %{display} =item B<--warning-status> diff --git a/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm b/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm index 7f89dc07c..a69d8b7db 100644 --- a/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm +++ b/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm @@ -245,7 +245,7 @@ Example: --filter-counters='^status$' =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{state}, %{display} =item B<--warning-status> diff --git a/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm b/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm index 583706772..040ed0d04 100644 --- a/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm +++ b/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm @@ -219,7 +219,7 @@ Filter snapvault name (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{state}, %{status}, %{display} =item B<--warning-status> diff --git a/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm b/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm index 1770ed5e7..0b4f11a0c 100644 --- a/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm +++ b/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm @@ -197,7 +197,7 @@ Filter on volume status (can be a regexp). =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status (Default: ''). Can used special variables like: %{status}, %{display} =item B<--warning-status> From 99af7a68f6172b15c24974a132ccfcae192a96e6 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Thu, 30 Mar 2023 14:04:11 +0200 Subject: [PATCH 371/447] (plugin) apps::nmap::cli - redirect stderr to null (#4324) --- src/apps/nmap/cli/mode/discovery.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/nmap/cli/mode/discovery.pm b/src/apps/nmap/cli/mode/discovery.pm index bdfd5fb38..2c2f6a54e 100644 --- a/src/apps/nmap/cli/mode/discovery.pm +++ b/src/apps/nmap/cli/mode/discovery.pm @@ -115,7 +115,7 @@ sub run { my ($stdout) = $options{custom}->execute_command( command => 'nmap', command_options => $self->{option_results}->{nmap_options}, - command_options_suffix => $self->{option_results}->{subnet}, + command_options_suffix => $self->{option_results}->{subnet} . ' 2> /dev/null', timeout => 120 ); @@ -187,7 +187,7 @@ __END__ =head1 MODE Resources discovery. -Default command used: nmap -sS -sU -R -O --osscan-limit --osscan-guess -p U:161,162,T:21-25,80,139,443,3306,8080,8443 -oX - __SUBNET_OPTION__ +Default command used: nmap -sS -sU -R -O --osscan-limit --osscan-guess -p U:161,162,T:21-25,80,139,443,3306,8080,8443 -oX - __SUBNET_OPTION__ 2> /dev/null Timeout defaults to 120 seconds. From 1402f7cad524c6db4241c3c2700d2ebc9e1ae9ff Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 5 Apr 2023 16:55:47 +0200 Subject: [PATCH 372/447] (plugin) network::aruba::cppm::snmp - new (#4325) --- .../deb.json | 5 + .../pkg.json | 14 ++ .../rpm.json | 5 + src/network/aruba/cppm/snmp/mode/cpu.pm | 68 +++++++ src/network/aruba/cppm/snmp/mode/disks.pm | 154 +++++++++++++++ .../aruba/cppm/snmp/mode/interfaces.pm | 182 ++++++++++++++++++ src/network/aruba/cppm/snmp/mode/memory.pm | 154 +++++++++++++++ src/network/aruba/cppm/snmp/mode/radius.pm | 156 +++++++++++++++ .../aruba/cppm/snmp/mode/repositories.pm | 143 ++++++++++++++ src/network/aruba/cppm/snmp/mode/tacacs.pm | 175 +++++++++++++++++ src/network/aruba/cppm/snmp/plugin.pm | 55 ++++++ 11 files changed, 1111 insertions(+) create mode 100644 packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/deb.json create mode 100644 packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/pkg.json create mode 100644 packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/rpm.json create mode 100644 src/network/aruba/cppm/snmp/mode/cpu.pm create mode 100644 src/network/aruba/cppm/snmp/mode/disks.pm create mode 100644 src/network/aruba/cppm/snmp/mode/interfaces.pm create mode 100644 src/network/aruba/cppm/snmp/mode/memory.pm create mode 100644 src/network/aruba/cppm/snmp/mode/radius.pm create mode 100644 src/network/aruba/cppm/snmp/mode/repositories.pm create mode 100644 src/network/aruba/cppm/snmp/mode/tacacs.pm create mode 100644 src/network/aruba/cppm/snmp/plugin.pm diff --git a/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/deb.json b/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/deb.json new file mode 100644 index 000000000..5d24d64c4 --- /dev/null +++ b/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libsnmp-perl" + ] +} diff --git a/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/pkg.json b/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/pkg.json new file mode 100644 index 000000000..a9dd65345 --- /dev/null +++ b/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/pkg.json @@ -0,0 +1,14 @@ +{ + "pkg_name": "centreon-plugin-Network-Aruba-Cppm-Snmp", + "pkg_summary": "Centreon Plugin to monitor Aruba ClearPass Policy Manager using SNMP", + "plugin_name": "centreon_aruba_cppm_snmp.pl", + "files": [ + "centreon/plugins/script_snmp.pm", + "centreon/plugins/snmp.pm", + "snmp_standard/mode/cpu.pm", + "snmp_standard/mode/listinterfaces.pm", + "snmp_standard/mode/resources/", + "snmp_standard/mode/interfaces.pm", + "network/aruba/cppm/snmp/" + ] +} diff --git a/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/rpm.json b/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/rpm.json new file mode 100644 index 000000000..14e966306 --- /dev/null +++ b/packaging/centreon-plugin-Network-Aruba-Cppm-Snmp/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(SNMP)" + ] +} diff --git a/src/network/aruba/cppm/snmp/mode/cpu.pm b/src/network/aruba/cppm/snmp/mode/cpu.pm new file mode 100644 index 000000000..cfe2392b5 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/cpu.pm @@ -0,0 +1,68 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::aruba::cppm::snmp::mode::cpu; + +use base qw(snmp_standard::mode::cpu); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system CPUs. + +=over 8 + +=item B<--use-ucd> + +Use UCD mib for cpu average. + +=item B<--warning-average> + +Warning threshold average CPU utilization. + +=item B<--critical-average> + +Critical threshold average CPU utilization. + +=item B<--warning-core> + +Warning thresholds for each CPU core + +=item B<--critical-core> + +Critical thresholds for each CPU core + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/mode/disks.pm b/src/network/aruba/cppm/snmp/mode/disks.pm new file mode 100644 index 000000000..9bd52a815 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/disks.pm @@ -0,0 +1,154 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::aruba::cppm::snmp::mode::disks; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_space_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_space}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used_space}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free_space}); + return sprintf( + 'space usage total: %s used: %s (%.2f%%) free: %s (%.2f%%)', + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used_space}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free_space} + ); +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance}. "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disks', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All disks are ok' } + ]; + + $self->{maps_counters}->{disks} = [ + { label => 'space-usage', nlabel => 'disk.space.usage.bytes', set => { + key_values => [ { name => 'used_space' }, { name => 'free_space' }, { name => 'prct_used_space' }, { name => 'prct_free_space' }, { name => 'total_space' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total_space', unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'space-usage-free', nlabel => 'disk.space.free.bytes', display_ok => 0, set => { + key_values => [ { name => 'free_space' }, { name => 'used_space' }, { name => 'prct_used_space' }, { name => 'prct_free_space' }, { name => 'total_space' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total_space', unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'space-usage-prct', nlabel => 'disk.space.usage.percentage', display_ok => 0, set => { + key_values => [ { name => 'prct_used_space' }, { name => 'used_space' }, { name => 'free_space' }, { name => 'prct_free_space' }, { name => 'total_space' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + hostname => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.4' }, # cppmSystemHostname + total => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.14' }, # cppmSystemDiskSpaceTotal + free => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.15' } # cppmSystemDiskSpaceFree + }; + my $oid_diskEntry = '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1'; + + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_diskEntry, start => $mapping->{total}->{oid}, end => $mapping->{free}->{oid} }, + { oid => $mapping->{hostname}->{oid} } + ], + return_type => 1, + nothing_quit => 1 + ); + + $self->{disks} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{hostname}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{hostname} !~ /$self->{option_results}->{filter_name}/); + + $self->{disks}->{ $result->{hostname} } = { + free_space => $result->{free}, + total_space => $result->{total}, + used_space => $result->{total} - $result->{free}, + prct_used_space => ($result->{total} - $result->{free}) * 100 / $result->{total}, + prct_free_space => $result->{free} * 100 / $result->{total}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check disks. + +=over 8 + +=item B<--filter-name> + +Filter disks by system hostname (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'space-usage', 'space-usage-free', 'space-usage-prct'. + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/mode/interfaces.pm b/src/network/aruba/cppm/snmp/mode/interfaces.pm new file mode 100644 index 000000000..3e3e91643 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/interfaces.pm @@ -0,0 +1,182 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::aruba::cppm::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--check-metrics> + +If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast', +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', 'bps', 'counter'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--units-cast> + +Units of thresholds for communication types (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--map-speed-dsl> + +Get interface speed configuration for interface type 'adsl' and 'vdsl2'. + +Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name + +E.g: --map-speed-dsl=Et0.835,Et0-vdsl2 + +=item B<--force-counters64> + +Force to use 64 bits counters only. Can be used to improve performance. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/mode/memory.pm b/src/network/aruba/cppm/snmp/mode/memory.pm new file mode 100644 index 000000000..06fab0150 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/memory.pm @@ -0,0 +1,154 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::aruba::cppm::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + return sprintf( + 'usage total: %s used: %s (%.2f%%) free: %s (%.2f%%)', + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free} + ); +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance}. "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memories', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memories are ok' } + ]; + + $self->{maps_counters}->{memories} = [ + { label => 'usage', nlabel => 'memory.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'usage-free', nlabel => 'memory.free.bytes', display_ok => 0, set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'usage-prct', nlabel => 'memory.usage.percentage', display_ok => 0, set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + hostname => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.4' }, # cppmSystemHostname + total => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.12' }, # cppmSystemMemoryTotal + free => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.13' } # cppmSystemMemoryFree + }; + my $oid_memEntry = '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1'; + + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_memEntry, start => $mapping->{total}->{oid}, end => $mapping->{free}->{oid} }, + { oid => $mapping->{hostname}->{oid} } + ], + return_type => 1, + nothing_quit => 1 + ); + + $self->{memories} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{hostname}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{hostname} !~ /$self->{option_results}->{filter_name}/); + + $self->{memories}->{ $result->{hostname} } = { + free => $result->{free}, + total => $result->{total}, + used => $result->{total} - $result->{free}, + prct_used => ($result->{total} - $result->{free}) * 100 / $result->{total}, + prct_free => $result->{free} * 100 / $result->{total}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check memory usages. + +=over 8 + +=item B<--filter-name> + +Filter memory by system hostname (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage', 'usage-free', 'usage-prct'. + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/mode/radius.pm b/src/network/aruba/cppm/snmp/mode/radius.pm new file mode 100644 index 000000000..3959dc077 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/radius.pm @@ -0,0 +1,156 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors : Alexandre Moreau (@SpyL1nk) + +package network::aruba::cppm::snmp::mode::radius; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_radius_output { + my ($self, %options) = @_; + + return "Radius '" . $options{instance}. "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'radius', type => 1, cb_prefix_output => 'prefix_radius_output', message_multiple => 'All radius statistics are ok' } + ]; + + $self->{maps_counters}->{radius} = [ + { label => 'radius-policy-eval', nlabel => 'radius.policy.evaluation.milliseconds', set => { + key_values => [ { name => 'policyEvalTime' } ], + output_template => 'policy evaluation time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'radius-requests-time', nlabel => 'radius.requests.milliseconds', set => { + key_values => [ { name => 'authRequestTime' } ], + output_template => 'requests time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'radius-requests', nlabel => 'radius.requests.count', set => { + key_values => [ { name => 'totalReq' } ], + output_template => 'total requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'radius-requests-failed', nlabel => 'radius.requests.failed.count', set => { + key_values => [ { name => 'failedReq' } ], + output_template => 'failed requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'radius-requests-succeeded', nlabel => 'radius.requests.succeeded.count', set => { + key_values => [ { name => 'successReq' } ], + output_template => 'succeeded requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + ]; +} + + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + hostname => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.4' }, # cppmSystemHostname + policyEvalTime => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.1.1.1' }, # radPolicyEvalTime + authRequestTime => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.1.1.2' }, # radAuthRequestTime + successReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.1.1.3' }, # radServerCounterSuccess + failedReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.1.1.4' }, # radServerCounterFailure + totalReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.1.1.5' } # radServerCounterCount + }; + my $oid_radiusEntry = '.1.3.6.1.4.1.14823.1.6.1.1.2.1.1'; + + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_radiusEntry }, + { oid => $mapping->{hostname}->{oid} } + ], + return_type => 1, + nothing_quit => 1 + ); + + $self->{radius} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{hostname}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{hostname} !~ /$self->{option_results}->{filter_name}/); + + $self->{radius}->{ $result->{hostname} } = $result; + } +} + +1; + +__END__ + +=head1 MODE + +Check radius statistics. + +=over 8 + +=item B<--filter-name> + +Filter radius by system hostname (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'radius-policy-eval', 'radius-requests-time', +'radius-requests', 'radius-requests-failed', 'radius-requests-succeeded'. + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/mode/repositories.pm b/src/network/aruba/cppm/snmp/mode/repositories.pm new file mode 100644 index 000000000..edc564a21 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/repositories.pm @@ -0,0 +1,143 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors : Alexandre Moreau (@SpyL1nk) + +package network::aruba::cppm::snmp::mode::repositories; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_repository_output { + my ($self, %options) = @_; + + return "Authentication repository '" . $options{instance}. "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'repositories', type => 1, cb_prefix_output => 'prefix_repository_output', message_multiple => 'All authentication repositories are ok' } + ]; + + $self->{maps_counters}->{repositories} = [ + { label => 'requests-time', nlabel => 'authentication_repository.requests.milliseconds', set => { + key_values => [ { name => 'timeReq' } ], + output_template => 'requests time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'requests', nlabel => 'authentication_repository.requests.count', set => { + key_values => [ { name => 'totalReq' } ], + output_template => 'total requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'requests-failed', nlabel => 'authentication_repository.requests.failed.count', set => { + key_values => [ { name => 'failedReq' } ], + output_template => 'failed requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'requests-succeeded', nlabel => 'authentication_repository.requests.succeeded.count', set => { + key_values => [ { name => 'successReq' } ], + output_template => 'succeeded requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; +} + + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + sourceName => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.2.1.2' }, # radAuthSourceName + successReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.2.1.3' }, # radAuthCounterSuccess + failedReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.2.1.4' }, # radAuthCounterFailure + totalReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.2.1.5' }, # radAuthCounterCount + timeReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.2.1.6' } # radAuthCounterTime + }; + my $oid_authEntry = '.1.3.6.1.4.1.14823.1.6.1.1.2.2.1'; + + my $snmp_result = $options{snmp}->get_table( + oid => $oid_authEntry, + nothing_quit => 1 + ); + + $self->{repositories} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{sourceName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{sourceName} !~ /$self->{option_results}->{filter_name}/); + + $self->{repositories}->{ $result->{sourceName} } = $result; + } +} + +1; + +__END__ + +=head1 MODE + +Check ClearPass authentication repository statistics. + +=over 8 + +=item B<--filter-name> + +Filter authentification repositories by system hostname (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'requests-time', 'requests', 'requests-failed', +'requests-succeeded'. + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/mode/tacacs.pm b/src/network/aruba/cppm/snmp/mode/tacacs.pm new file mode 100644 index 000000000..463c5df65 --- /dev/null +++ b/src/network/aruba/cppm/snmp/mode/tacacs.pm @@ -0,0 +1,175 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors : Alexandre Moreau (@SpyL1nk) + +package network::aruba::cppm::snmp::mode::tacacs; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_tacacs_auth_output { + my ($self, %options) = @_; + + return "Tacacs authentication '" . $options{instance}. "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'tacacs_auth', type => 1, cb_prefix_output => 'prefix_tacacs_auth_output', message_multiple => 'All tacas+ authentication are ok' } + ]; + + $self->{maps_counters}->{tacacs_auth} = [ + { label => 'tacacs-auth-policy-eval', nlabel => 'tacacs.authentication.policy.evaluation.milliseconds', set => { + key_values => [ { name => 'policyEvalTime' } ], + output_template => 'policy evaluation time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'tacacs-auth-policy-eval', nlabel => 'tacacs.authentication.service.policy.evaluation.milliseconds', set => { + key_values => [ { name => 'servicePolicyEvalTime' } ], + output_template => 'service policy evaluation time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'tacacs-auth-requests-auth-time', nlabel => 'tacacs.authentication.requests.authentication.time.milliseconds', set => { + key_values => [ { name => 'authTimeReq' } ], + output_template => 'requests authentication time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'tacacs-auth-requests-time', nlabel => 'tacacs.authentication.requests.time.milliseconds', set => { + key_values => [ { name => 'timeReq' } ], + output_template => 'requests time: %s ms', + perfdatas => [ + { template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'tacacs-auth-requests', nlabel => 'tacacs.authentication.requests.count', set => { + key_values => [ { name => 'totalReq' } ], + output_template => 'total requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'tacacs-auth-requests-failed', nlabel => 'tacacs.authentication.requests.failed.count', set => { + key_values => [ { name => 'failedReq' } ], + output_template => 'failed requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'tacacs-auth-requests-succeeded', nlabel => 'tacacs.authentication.requests.succeeded.count', set => { + key_values => [ { name => 'successReq' } ], + output_template => 'succeeded requests: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; +} + + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + hostname => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.1.1.1.4' }, # cppmSystemHostname + successReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.1' }, # tacAuthCounterSuccess + failedReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.2' }, # tacAuthCounterFailure + totalReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.3' }, # tacAuthCounterCount + timeReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.4' }, # tacAuthCounterTime + authTimeReq => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.5' }, # tacAuthCounterAuthTime + servicePolicyEvalTime => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.6' }, # tacServicePolicyEvalTime + policyEvalTime => { oid => '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1.7' } # tacPolicyEvalTime + }; + my $oid_tacacsAuthEntry = '.1.3.6.1.4.1.14823.1.6.1.1.2.7.1'; + + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_tacacsAuthEntry }, + { oid => $mapping->{hostname}->{oid} } + ], + return_type => 1, + nothing_quit => 1 + ); + + $self->{tacacs_auth} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{hostname}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{hostname} !~ /$self->{option_results}->{filter_name}/); + + $self->{tacacs_auth}->{ $result->{hostname} } = $result; + } +} + +1; + +__END__ + +=head1 MODE + +Check TACACS+ statistics. + +=over 8 + +=item B<--filter-name> + +Filter tacacs by system hostname (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'tacacs-auth-policy-eval', 'tacacs-auth-policy-eval', 'tacacs-auth-requests-auth-time',' +'tacacs-auth-requests-time', 'tacacs-auth-requests', 'tacacs-auth-requests-failed', +'tacacs-auth-requests-succeeded'. + +=back + +=cut diff --git a/src/network/aruba/cppm/snmp/plugin.pm b/src/network/aruba/cppm/snmp/plugin.pm new file mode 100644 index 000000000..cbc514d2e --- /dev/null +++ b/src/network/aruba/cppm/snmp/plugin.pm @@ -0,0 +1,55 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors : Alexandre Moreau (@SpyL1nk) + +package network::aruba::cppm::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'cpu' => 'network::aruba::cppm::snmp::mode::cpu', + 'disks' => 'network::aruba::cppm::snmp::mode::disks', + 'interfaces' => 'network::aruba::cppm::snmp::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::aruba::cppm::snmp::mode::memory', + 'radius' => 'network::aruba::cppm::snmp::mode::radius', + 'repositories' => 'network::aruba::cppm::snmp::mode::repositories', + 'tacacs' => 'network::aruba::cppm::snmp::mode::tacacs' + }; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Aruba ClearPass Policy Manager in SNMP. + +=cut From 91707f0a3e8fb4a64cf8a9739d87aaaf4d308d3a Mon Sep 17 00:00:00 2001 From: sdepassio <114986849+sdepassio@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:25:10 +0200 Subject: [PATCH 373/447] (plugin)cloud::azure::policyinsights::policystates - fix (#4338) * fix * update * update regex * add loop on nextlink * Add filter policy name * fix --- src/cloud/azure/custom/api.pm | 58 +++++++++++-------- .../policystates/mode/compliance.pm | 10 +++- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/cloud/azure/custom/api.pm b/src/cloud/azure/custom/api.pm index f4e6a8dfc..ab472e781 100644 --- a/src/cloud/azure/custom/api.pm +++ b/src/cloud/azure/custom/api.pm @@ -1194,38 +1194,50 @@ sub azure_list_policystates { 'api-version', $self->{api_version}, '$select', 'ResourceId, ResourceType, ResourceLocation, ResourceGroup, PolicyDefinitionName, IsCompliant, ComplianceState' ]; - my $resource_location; + my @filters = (); if (length $options{resource_location}) { - $resource_location = ("ResourceLocation eq '" . $options{resource_location} . "'"); - delete $options{$resource_location}; + push(@filters, ("ResourceLocation eq '" . $options{resource_location} . "'")); + delete $options{resource_location}; } - my $resource_type; if (length $options{resource_type}) { - $resource_type = ("ResourceType eq '" . $options{resource_type} . "'"); - delete $options{$resource_type}; + push(@filters, ("ResourceType eq '" . $options{resource_type} . "'")); + delete $options{resource_type}; } - my $filter; - if (length $resource_location && length $resource_type) { - $filter = $resource_location . " and " . $resource_type; - } elsif (length $resource_location) { - $filter = $resource_location - } elsif (length $resource_type) { - $filter = $resource_type + if (length $options{policy_name}) { + push(@filters, ("PolicyDefinitionName eq '" . $options{policy_name} . "'")); + delete $options{policy_name}; } - if (length($filter)) { - push(@$get_params, '$filter', $filter); + my $filterRequest; + foreach my $filter (@filters) { + if (!defined($filterRequest)) { + $filterRequest = $filter; + } else { + $filterRequest .= " and " . $filter; + } + } + if (length$filterRequest) { + push(@$get_params, '$filter', $filterRequest); } my ($url) = $self->azure_set_url(%options); - my $response = $self->request_api( - method => 'POST', - full_url => $url, - hostname => '', - header => ['Content-Type: application/json'], - get_params => $get_params - ); + my $full_response = []; + while (1) { + my $response = $self->request_api( + method => 'POST', + full_url => $url, + hostname => '', + get_params => $get_params, + query_form_post => '' + ); + foreach (@{$response->{value}}) { + push @$full_response, $_; + } - return $response->{value}; + last if (!defined($response->{'@odata.nextLink'})); + $url = $response->{'@odata.nextLink'}; + } + + return $full_response; } 1; diff --git a/src/cloud/azure/policyinsights/policystates/mode/compliance.pm b/src/cloud/azure/policyinsights/policystates/mode/compliance.pm index 4c2838f44..d86eabf89 100644 --- a/src/cloud/azure/policyinsights/policystates/mode/compliance.pm +++ b/src/cloud/azure/policyinsights/policystates/mode/compliance.pm @@ -71,6 +71,7 @@ sub new { $options{options}->add_options(arguments => { 'api-version:s' => { name => 'api_version', default => '2019-10-01'}, 'policy-states:s' => { name => 'policy_states', default => 'default' }, + 'policy-name:s' => { name => 'policy_name' }, 'resource-group:s' => { name => 'resource_group' }, 'resource-location:s' => { name => 'resource_location' }, 'resource-type:s' => { name => 'resource_type' } @@ -95,14 +96,15 @@ sub manage_selection { resource_group => $self->{option_results}->{resource_group}, query_name => 'queryResults', resource_location => $self->{option_results}->{resource_location}, - resource_type => $self->{option_results}->{resource_type} + resource_type => $self->{option_results}->{resource_type}, + policy_name => $self->{option_results}->{policy_name} ); my $non_compliant_policies = 0; $self->{compliance_state} = {}; foreach my $policy_state (@{ $policy_states }) { my $resource_name = $policy_state->{resourceId}; - $resource_name =~ /.*\/(\w*)$/; + $resource_name =~ /(\w*)$/; $resource_name = $1; my $display = $policy_state->{policyDefinitionName} . "_" . $resource_name; $self->{compliance_state}->{ $display } = { @@ -148,6 +150,10 @@ Set resource location (Optional). Set resource type (Optional). +=item B<--policy-name> + +Set policy name (Optional). + =item B<--warning-*> B<--critical-*> Thresholds. From e69ec9de6e9fb5f6844a3086538673bfd7ef05ca Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 11 Apr 2023 16:28:16 +0200 Subject: [PATCH 374/447] (plugin) network::opengear::snmp - new (#4328) --- .../deb.json | 5 + .../pkg.json | 17 ++ .../rpm.json | 5 + src/network/opengear/snmp/mode/cpudetailed.pm | 59 ++++ src/network/opengear/snmp/mode/interfaces.pm | 182 ++++++++++++ .../opengear/snmp/mode/listserialports.pm | 108 +++++++ src/network/opengear/snmp/mode/load.pm | 60 ++++ src/network/opengear/snmp/mode/memory.pm | 67 +++++ src/network/opengear/snmp/mode/serialports.pm | 264 ++++++++++++++++++ src/network/opengear/snmp/mode/uptime.pm | 77 +++++ src/network/opengear/snmp/plugin.pm | 54 ++++ 11 files changed, 898 insertions(+) create mode 100644 packaging/centreon-plugin-Network-Opengear-Snmp/deb.json create mode 100644 packaging/centreon-plugin-Network-Opengear-Snmp/pkg.json create mode 100644 packaging/centreon-plugin-Network-Opengear-Snmp/rpm.json create mode 100644 src/network/opengear/snmp/mode/cpudetailed.pm create mode 100644 src/network/opengear/snmp/mode/interfaces.pm create mode 100644 src/network/opengear/snmp/mode/listserialports.pm create mode 100644 src/network/opengear/snmp/mode/load.pm create mode 100644 src/network/opengear/snmp/mode/memory.pm create mode 100644 src/network/opengear/snmp/mode/serialports.pm create mode 100644 src/network/opengear/snmp/mode/uptime.pm create mode 100644 src/network/opengear/snmp/plugin.pm diff --git a/packaging/centreon-plugin-Network-Opengear-Snmp/deb.json b/packaging/centreon-plugin-Network-Opengear-Snmp/deb.json new file mode 100644 index 000000000..5d24d64c4 --- /dev/null +++ b/packaging/centreon-plugin-Network-Opengear-Snmp/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libsnmp-perl" + ] +} diff --git a/packaging/centreon-plugin-Network-Opengear-Snmp/pkg.json b/packaging/centreon-plugin-Network-Opengear-Snmp/pkg.json new file mode 100644 index 000000000..7ca5c35e3 --- /dev/null +++ b/packaging/centreon-plugin-Network-Opengear-Snmp/pkg.json @@ -0,0 +1,17 @@ +{ + "pkg_name": "centreon-plugin-Network-Opengear-Snmp", + "pkg_summary": "Centreon Plugin Opengear SNMP", + "plugin_name": "centreon_opengear_snmp.pl", + "files": [ + "centreon/plugins/script_snmp.pm", + "centreon/plugins/snmp.pm", + "snmp_standard/mode/cpudetailed.pm", + "snmp_standard/mode/interfaces.pm", + "snmp_standard/mode/listinterfaces.pm", + "snmp_standard/mode/loadaverage.pm", + "snmp_standard/mode/memory.pm", + "snmp_standard/mode/resources/", + "snmp_standard/mode/uptime.pm", + "network/opengear/snmp/" + ] +} diff --git a/packaging/centreon-plugin-Network-Opengear-Snmp/rpm.json b/packaging/centreon-plugin-Network-Opengear-Snmp/rpm.json new file mode 100644 index 000000000..14e966306 --- /dev/null +++ b/packaging/centreon-plugin-Network-Opengear-Snmp/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(SNMP)" + ] +} diff --git a/src/network/opengear/snmp/mode/cpudetailed.pm b/src/network/opengear/snmp/mode/cpudetailed.pm new file mode 100644 index 000000000..8d5d8c7ee --- /dev/null +++ b/src/network/opengear/snmp/mode/cpudetailed.pm @@ -0,0 +1,59 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::cpudetailed; + +use base qw(snmp_standard::mode::cpudetailed); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system CPUs (UCD-SNMP-MIB) (User, Nice, System, Idle, Wait, Kernel, Interrupt, SoftIRQ, Steal, Guest, GuestNice) +An average of all CPUs. + +=over 8 + +=item B<--warning-*> + +Threshold warning in percent. +Can be: 'user', 'nice', 'system', 'idle', 'wait', 'kernel', 'interrupt', 'softirq', 'steal', 'guest', 'guestnice'. + +=item B<--critical-*> + +Threshold critical in percent. +Can be: 'user', 'nice', 'system', 'idle', 'wait', 'kernel', 'interrupt', 'softirq', 'steal', 'guest', 'guestnice'. + +=back + +=cut diff --git a/src/network/opengear/snmp/mode/interfaces.pm b/src/network/opengear/snmp/mode/interfaces.pm new file mode 100644 index 000000000..e2c9da614 --- /dev/null +++ b/src/network/opengear/snmp/mode/interfaces.pm @@ -0,0 +1,182 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--check-metrics> + +If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast', +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', 'bps', 'counter'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--units-cast> + +Units of thresholds for communication types (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--map-speed-dsl> + +Get interface speed configuration for interface type 'adsl' and 'vdsl2'. + +Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name + +E.g: --map-speed-dsl=Et0.835,Et0-vdsl2 + +=item B<--force-counters64> + +Force to use 64 bits counters only. Can be used to improve performance. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/src/network/opengear/snmp/mode/listserialports.pm b/src/network/opengear/snmp/mode/listserialports.pm new file mode 100644 index 000000000..755fbe00e --- /dev/null +++ b/src/network/opengear/snmp/mode/listserialports.pm @@ -0,0 +1,108 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::listserialports; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_label = '.1.3.6.1.4.1.25049.16.1.1.11'; # ogSerialPortStatusLabel + my $snmp_result = $options{snmp}->get_table(oid => $oid_label); + + my $ports = {}; + foreach (keys %$snmp_result) { + $ports->{ $snmp_result->{$_} } = 1; + } + + return $ports; +} + +sub run { + my ($self, %options) = @_; + + my $ports = $self->manage_selection(%options); + foreach (sort keys %$ports) { + $self->{output}->output_add( + long_msg => sprintf( + '[name: %s]', + $_ + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List serial ports:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $ports = $self->manage_selection(%options); + foreach (sort keys %$ports) { + $self->{output}->add_disco_entry( + name => $_ + ); + } +} + +1; + +__END__ + +=head1 MODE + +List serial ports. + +=over 8 + +=back + +=cut + diff --git a/src/network/opengear/snmp/mode/load.pm b/src/network/opengear/snmp/mode/load.pm new file mode 100644 index 000000000..a8ea84d63 --- /dev/null +++ b/src/network/opengear/snmp/mode/load.pm @@ -0,0 +1,60 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::load; + +use base qw(snmp_standard::mode::loadaverage); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system load-average. + +=over 8 + +=item B<--warning> + +Threshold warning (1min,5min,15min). + +=item B<--critical> + +Threshold critical (1min,5min,15min). + +=item B<--average> + +Load average for the number of CPUs. + +=back + +=cut diff --git a/src/network/opengear/snmp/mode/memory.pm b/src/network/opengear/snmp/mode/memory.pm new file mode 100644 index 000000000..73188df26 --- /dev/null +++ b/src/network/opengear/snmp/mode/memory.pm @@ -0,0 +1,67 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::memory; + +use base qw(snmp_standard::mode::memory); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage (UCD-SNMP-MIB). + +=over 8 + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute') (Deprecated. Please use new counters directly) + +=item B<--free> + +Thresholds are on free space left (Deprecated. Please use new counters directly) + +=item B<--swap> + +Check swap also. + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%), +'swap' (B), 'swap-free' (B), 'swap-prct' (%), +'buffer' (B), 'cached' (B), 'shared' (B). + +=back + +=cut diff --git a/src/network/opengear/snmp/mode/serialports.pm b/src/network/opengear/snmp/mode/serialports.pm new file mode 100644 index 000000000..53a7d79ba --- /dev/null +++ b/src/network/opengear/snmp/mode/serialports.pm @@ -0,0 +1,264 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::serialports; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my ($warning, $critical); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq 'percent_delta' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} =~ /bps|counter/) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); + } + + if ($self->{instance_mode}->{option_results}->{units_traffic} eq 'counter') { + my $nlabel = $self->{nlabel}; + $nlabel =~ s/bitspersecond/bits/; + $self->{output}->perfdata_add( + nlabel => $nlabel, + unit => 'b', + instances => $self->{result_values}->{name}, + value => $self->{result_values}->{traffic_counter}, + warning => $warning, + critical => $critical, + min => 0 + ); + } else { + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => $self->{result_values}->{name}, + value => sprintf('%.2f', $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); + } +} + +sub custom_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($self->{instance_mode}->{option_results}->{units_traffic} eq 'percent_delta' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'bps') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'counter') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_counter}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic_per_seconds}, network => 1); + return sprintf( + 'traffic %s: %s/s (%s)', + $self->{result_values}->{label}, $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf('%.2f%%', $self->{result_values}->{traffic_prct}) : '-' + ); +} + +sub custom_traffic_calc { + my ($self, %options) = @_; + + my $diff_traffic = ($options{new_datas}->{ $self->{instance} . '_' . $options{extra_options}->{label_ref} } - $options{old_datas}->{ $self->{instance} . '_' . $options{extra_options}->{label_ref} }); + $self->{result_values}->{traffic_per_seconds} = $diff_traffic / $options{delta_time}; + $self->{result_values}->{traffic_counter} = $options{new_datas}->{ $self->{instance} . '_' . $options{extra_options}->{label_ref} }; + if (defined($options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}) && + $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}} > 0) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic_per_seconds} * 100 / $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{speed} = $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}; + } + + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{name} = $options{new_datas}->{ $self->{instance} . '_name' }; + return 0; +} + +sub prefix_interface_output { + my ($self, %options) = @_; + + return "Serial port '" . $options{instance_value}->{name} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'interfaces', type => 1, cb_prefix_output => 'prefix_interface_output', message_multiple => 'All interfaces are ok', cb_init_counters => 'skip_counters', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{interfaces} = [ + { label => 'traffic-in', nlabel => 'serial_port.traffic.in.bitspersecond', set => { + key_values => [ { name => 'in', diff => 1 }, { name => 'speed_in' }, { name => 'name' } ], + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'traffic in: %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold') + } + }, + { label => 'traffic-out', nlabel => 'serial_port.traffic.out.bitspersecond', set => { + key_values => [ { name => 'out', diff => 1 }, { name => 'speed_out' }, { name => 'name' } ], + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'traffic out: %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold') + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'units-traffic:s' => { name => 'units_traffic', default => 'percent_delta' }, + 'speed:s' => { name => 'speed' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + if ($self->{option_results}->{speed} !~ /^[0-9]+(\.[0-9]+){0,1}$/) { + $self->{output}->add_option_msg(short_msg => "Speed must be a positive number '" . $self->{option_results}->{speed} . "' (can be a float also)."); + $self->{output}->option_exit(); + } else { + $self->{option_results}->{speed} *= 1000000; + } + } + + $self->{option_results}->{units_traffic} = 'percent_delta' + if (!defined($self->{option_results}->{units_traffic}) || + $self->{option_results}->{units_traffic} eq '' || + $self->{option_results}->{units_traffic} eq '%'); + if ($self->{option_results}->{units_traffic} !~ /^(?:percent|percent_delta|bps|counter)$/) { + $self->{output}->add_option_msg(short_msg => 'Wrong option --units-traffic.'); + $self->{output}->option_exit(); + } +} + +my $mapping = { + rxBytes => { oid => '.1.3.6.1.4.1.25049.16.1.1.3' }, # ogSerialPortStatusRxBytes + txBytes => { oid => '.1.3.6.1.4.1.25049.16.1.1.4' }, # ogSerialPortStatusTxBytes + speed => { oid => '.1.3.6.1.4.1.25049.16.1.1.5' } # ogSerialPortStatusSpeed +}; + +sub manage_selection { + my ($self, %options) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => 'Need to use SNMP v2c or v3.'); + $self->{output}->option_exit(); + } + + my $oid_label = '.1.3.6.1.4.1.25049.16.1.1.11'; # ogSerialPortStatusLabel + my $snmp_result = $options{snmp}->get_table( + oid => $oid_label, + nothing_quit => 1 + ); + + $self->{interfaces} = {}; + foreach (keys %$snmp_result) { + /\.(\d+)$/; + my $instance = $1; + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$_} !~ /$self->{option_results}->{filter_name}/); + + $self->{interfaces}->{$instance} = { name => $snmp_result->{$_} }; + } + + return if (scalar(keys %{$self->{interfaces}}) <= 0); + + $options{snmp}->load( + oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [ map($_, keys %{$self->{interfaces}}) ], + instance_regexp => '^(.*)$' + ); + $snmp_result = $options{snmp}->get_leef(); + + foreach (keys %{$self->{interfaces}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + $self->{interfaces}->{$_}->{in} = $result->{rxBytes}; + $self->{interfaces}->{$_}->{out} = $result->{txBytes}; + $self->{interfaces}->{$_}->{speed_in} = defined($self->{option_results}->{speed}) ? $self->{option_results}->{speed} : $result->{speed}; + $self->{interfaces}->{$_}->{speed_out} = defined($self->{option_results}->{speed}) ? $self->{option_results}->{speed} : $result->{speed}; + } + + $self->{cache_name} = 'opengear_' . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + md5_hex( + (defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : 'all') . + (defined($self->{option_results}->{filter_name}) ? $self->{option_results}->{filter_name} : 'all') + ); +} + +1; + +__END__ + +=head1 MODE + +Check serial ports. + +=over 8 + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', 'bps', 'counter'). + +=item B<--filter-name> + +Filter serial port name (regexp can be used). + +=item B<--speed> + +Set serial port speed (in Mb). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'traffic-in', 'traffic-out'. + +=back + +=cut diff --git a/src/network/opengear/snmp/mode/uptime.pm b/src/network/opengear/snmp/mode/uptime.pm new file mode 100644 index 000000000..fe4cfe6ab --- /dev/null +++ b/src/network/opengear/snmp/mode/uptime.pm @@ -0,0 +1,77 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::mode::uptime; + +use base qw(snmp_standard::mode::uptime); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system uptime. + +=over 8 + +=item B<--warning-uptime> + +Threshold warning. + +=item B<--critical-uptime> + +Threshold critical. + +=item B<--add-sysdesc> + +Display system description. + +=item B<--force-oid> + +Can choose your oid (numeric format only). + +=item B<--check-overload> + +Uptime counter limit is 4294967296 and overflow. +With that option, we manage the counter going back. But there is a few chance we can miss a reboot. + +=item B<--reboot-window> + +To be used with check-overload option. Time in milliseconds (Default: 5000) +You increase the chance of not missing a reboot if you decrease that value. + +=item B<--unit> + +Select the unit for performance data and thresholds. May be 's' for seconds, 'm' for minutes, +'h' for hours, 'd' for days, 'w' for weeks. Default is seconds + +=back diff --git a/src/network/opengear/snmp/plugin.pm b/src/network/opengear/snmp/plugin.pm new file mode 100644 index 000000000..57aba5ee6 --- /dev/null +++ b/src/network/opengear/snmp/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::opengear::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'cpu-detailed' => 'network::opengear::snmp::mode::cpudetailed', + 'interfaces' => 'network::opengear::snmp::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-serial-ports' => 'network::opengear::snmp::mode::listserialports', + 'load' => 'network::opengear::snmp::mode::load', + 'memory' => 'network::opengear::snmp::mode::memory', + 'serial-ports' => 'network::opengear::snmp::mode::serialports', + 'uptime' => 'network::opengear::snmp::mode::uptime' + }; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Opengear in SNMP. + +=cut From 172097105905b7a1c97ee2fa84cf97c7498c8236 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 11 Apr 2023 16:28:29 +0200 Subject: [PATCH 375/447] (plugin) storage::netapp::ontap::restapi - mode quotas change filters (#4339) --- src/storage/netapp/ontap/restapi/mode/quotas.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/quotas.pm b/src/storage/netapp/ontap/restapi/mode/quotas.pm index 0379d9475..d2c3e5758 100644 --- a/src/storage/netapp/ontap/restapi/mode/quotas.pm +++ b/src/storage/netapp/ontap/restapi/mode/quotas.pm @@ -274,11 +274,11 @@ sub manage_selection { next if (defined($self->{option_results}->{filter_index}) && $self->{option_results}->{filter_index} ne '' && $index !~ /$self->{option_results}->{filter_index}/); - next if ($qtree ne '' && defined($self->{option_results}->{filter_qtree}) && $self->{option_results}->{filter_qtree} ne '' && + next if (defined($self->{option_results}->{filter_qtree}) && $self->{option_results}->{filter_qtree} ne '' && $qtree !~ /$self->{option_results}->{filter_qtree}/); - next if ($volume ne '' && defined($self->{option_results}->{filter_volume}) && $self->{option_results}->{filter_volume} ne '' && + next if (defined($self->{option_results}->{filter_volume}) && $self->{option_results}->{filter_volume} ne '' && $volume !~ /$self->{option_results}->{filter_volume}/); - next if ($vserver ne '' && defined($self->{option_results}->{filter_vserver}) && $self->{option_results}->{filter_vserver} ne '' && + next if (defined($self->{option_results}->{filter_vserver}) && $self->{option_results}->{filter_vserver} ne '' && $vserver !~ /$self->{option_results}->{filter_vserver}/); my $path = $vserver . $volume . $qtree; From a8895620fa10f1194d62e958f4d0be4f35a6d391 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 12 Apr 2023 09:11:20 +0200 Subject: [PATCH 376/447] (plugin) apps::antivirus::clamav - mode update-status fix txt dns record resolve (#4331) --- src/apps/antivirus/clamav/local/mode/updatestatus.pm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/apps/antivirus/clamav/local/mode/updatestatus.pm b/src/apps/antivirus/clamav/local/mode/updatestatus.pm index 0d98fa633..56e250204 100644 --- a/src/apps/antivirus/clamav/local/mode/updatestatus.pm +++ b/src/apps/antivirus/clamav/local/mode/updatestatus.pm @@ -125,13 +125,15 @@ sub get_clamav_last_update { #0.99.2:57:23114:1487851834:1:63:45614:290 # field 2 = main.cvd version number # field 3 = daily.cvd version number - my $nameservers = []; + my %dns_options = (); if (defined($self->{option_results}->{nameservers})) { - $nameservers = [@{$self->{option_results}->{nameservers}}]; + foreach my $dns (@{$self->{option_results}->{nameservers}}) { + next if ($dns !~ /[a-zA-Z0-9]/); + $dns_options{nameservers} = [] if (!defined($dns_options{nameservers})); + push @{$dns_options{nameservers}}, $dns; + } } - my $handle = Net::DNS::Resolver->new( - nameservers => $nameservers - ); + my $handle = Net::DNS::Resolver->new(%dns_options); my $txt_query = $handle->query("current.cvd.clamav.net", "TXT"); if (!$txt_query) { $self->{output}->add_option_msg(short_msg => "Unable to get TXT Record : " . $handle->errorstring . "."); From 920a45ca6285af9fe8219262368de4b94a20f2c0 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 12 Apr 2023 09:11:32 +0200 Subject: [PATCH 377/447] (plugin) os::linux::local - mode pending-updates change rhel security command (#4330) --- src/os/linux/local/mode/pendingupdates.pm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/os/linux/local/mode/pendingupdates.pm b/src/os/linux/local/mode/pendingupdates.pm index c7523f536..3c150b889 100644 --- a/src/os/linux/local/mode/pendingupdates.pm +++ b/src/os/linux/local/mode/pendingupdates.pm @@ -104,7 +104,9 @@ sub check_options { ) { $self->{command} = 'yum'; $self->{command_options} = 'check-update 2>&1'; - $self->{command_options} .= ' --security' if defined($self->{option_results}->{check_security}); + if defined($self->{option_results}->{check_security}) { + $self->{command_options} = '-q updateinfo list sec' + } } elsif ($self->{option_results}->{os_mode} eq 'debian') { $self->{command} = 'apt-get'; $self->{command_options} = 'upgrade -sVq 2>&1'; @@ -157,11 +159,10 @@ sub parse_updates { sub parse_security_updates { my ($self, %options) = @_; - my @lines = split /\n/, $options{stdout}; + my @lines = split(/\n/, $options{stdout}); + $self->{global}->{total_security} = 0; foreach my $line (@lines) { - next if ($line !~ /^(\d+).package\(s\)/); - my $security_updates = $1; - $self->{global}->{total_security} = $security_updates; + $self->{global}->{total_security}++; } } @@ -200,6 +201,7 @@ __END__ Check pending updates. For rhel/centos: yum check-update 2>&1 +For rhel/centos security: yum -q updateinfo list sec For Debian: apt-get upgrade -sVq 2>&1 For Suse: zypper list-updates 2>&1 From cbe6b47742e6b4f10f714d832901fb55c0ecdd08 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 12 Apr 2023 10:53:09 +0200 Subject: [PATCH 378/447] add password manager secret file (#4329) --- src/centreon/plugins/passwordmgr/file.pm | 176 +++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 src/centreon/plugins/passwordmgr/file.pm diff --git a/src/centreon/plugins/passwordmgr/file.pm b/src/centreon/plugins/passwordmgr/file.pm new file mode 100644 index 000000000..866827b76 --- /dev/null +++ b/src/centreon/plugins/passwordmgr/file.pm @@ -0,0 +1,176 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::plugins::passwordmgr::file; + +use strict; +use warnings; +use centreon::plugins::misc; +use JSON::Path; +use JSON::XS; +use Data::Dumper; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class PasswordMgr: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class PasswordMgr: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + $options{options}->add_options(arguments => { + 'secret-file:s' => { name => 'secret_file' }, + 'secret-search-value:s@' => { name => 'secret_search_value' }, + 'secret-map-option:s@' => { name => 'secret_map_option' } + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'SECRET FILE OPTIONS'); + + $self->{output} = $options{output}; + $JSON::Path::Safe = 0; + + return $self; +} + +sub load { + my ($self, %options) = @_; + + if (defined($options{option_results}->{secret_file}) && $options{option_results}->{secret_file} ne '') { + if (! -f $options{option_results}->{secret_file} or ! -r $options{option_results}->{secret_file}) { + $self->{output}->add_option_msg(short_msg => "Cannot read secret file '$options{option_results}->{secret_file}': $!"); + $self->{output}->option_exit(); + } + + my $content = centreon::plugins::misc::slurp_file(output => $self->{output}, file => $options{option_results}->{secret_file}); + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode secret file"); + $self->{output}->option_exit(); + } + + return $decoded; + } +} + +sub do_lookup { + my ($self, %options) = @_; + + $self->{lookup_values} = {}; + return if (!defined($options{option_results}->{secret_search_value})); + + foreach (@{$options{option_results}->{secret_search_value}}) { + next if (! /^(.+?)=(.+)$/); + my ($map, $lookup) = ($1, $2); + + # Change %{xxx} options usage + while ($lookup =~ /\%\{(.*?)\}/g) { + my $sub = ''; + $sub = $options{option_results}->{$1} if (defined($options{option_results}->{$1})); + $lookup =~ s/\%\{$1\}/$sub/g + } + + my $jpath = JSON::Path->new($lookup); + my $result = $jpath->value($options{json}); + $self->{output}->output_add(long_msg => 'lookup = ' . $lookup. ' - response = ' . Data::Dumper::Dumper($result), debug => 1); + $self->{lookup_values}->{$map} = $result; + } +} + +sub do_map { + my ($self, %options) = @_; + + return if (!defined($options{option_results}->{secret_map_option})); + foreach (@{$options{option_results}->{secret_map_option}}) { + next if (! /^(.+?)=(.+)$/); + my ($option, $map) = ($1, $2); + + # Change %{xxx} options usage + while ($map =~ /\%\{(.*?)\}/g) { + my $sub = ''; + $sub = $self->{lookup_values}->{$1} if (defined($self->{lookup_values}->{$1})); + $map =~ s/\%\{$1\}/$sub/g + } + + $option =~ s/-/_/g; + $options{option_results}->{$option} = $map; + } +} + +sub manage_options { + my ($self, %options) = @_; + + my $secrets = $self->load(%options); + return if (!defined($secrets)); + + $self->do_lookup(%options, json => $secrets); + $self->do_map(%options); +} + +1; + +__END__ + +=head1 NAME + +Secret file global + +=head1 SYNOPSIS + +secret file class + +=head1 SECRET FILE OPTIONS + +=over 8 + +=item B<--secret-file> + +Secret file. + +=item B<--secret-search-value> + +Looking for a value in the JSON. Can use JSON Path and other option values. +Example: +--secret-search-value='password=$..entries.[?($_->{title} =~ /server/i)].password' +--secret-search-value='username=$..entries.[?($_->{title} =~ /server/i)].username' +--secret-search-value='password=$..entries.[?($_->{title} =~ /%{hostname}/i)].password' + +=item B<--secret-map-option> + +Overload plugin option. +Example: +--secret-map-option="password=%{password}" +--secret-map-option="username=%{username}" + +=back + +=head1 DESCRIPTION + +B. + +=cut From 4f6ab289028b0ad4b831b8b38e49ea06f41cc50c Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 12 Apr 2023 11:56:23 +0200 Subject: [PATCH 379/447] (plugin) storage::netapp::ontap::snmp - mode global-status harden code check (#4341) --- .../netapp/ontap/snmp/mode/globalstatus.pm | 70 +++++++++++-------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/src/storage/netapp/ontap/snmp/mode/globalstatus.pm b/src/storage/netapp/ontap/snmp/mode/globalstatus.pm index 3be6b01d1..579b443e7 100644 --- a/src/storage/netapp/ontap/snmp/mode/globalstatus.pm +++ b/src/storage/netapp/ontap/snmp/mode/globalstatus.pm @@ -32,7 +32,7 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'global', type => 0, skipped_code => { -10 => 1 } } ]; - + $self->{maps_counters}->{global} = [ { label => 'read', nlabel => 'storage.io.read.usage.bytespersecond', set => { key_values => [ { name => 'read', per_second => 1 } ], @@ -60,8 +60,7 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; - $options{options}->add_options(arguments => { - }); + $options{options}->add_options(arguments => {}); return $self; } @@ -72,12 +71,12 @@ my %states = ( 3 => ['ok', 'OK'], 4 => ['non critical', 'WARNING'], 5 => ['critical', 'CRITICAL'], - 6 => ['nonRecoverable', 'WARNING'], + 6 => ['nonRecoverable', 'WARNING'] ); my %fs_states = ( - 1 => ['ok', 'OK'], - 2 => ['nearly full', 'WARNING'], - 3 => ['full', 'CRITICAL'], + 1 => ['ok', 'OK'], + 2 => ['nearly full', 'WARNING'], + 3 => ['full', 'CRITICAL'] ); my $oid_fsOverallStatus = '.1.3.6.1.4.1.789.1.5.7.1.0'; @@ -103,25 +102,42 @@ sub manage_selection { if (!$options{snmp}->is_snmpv1()) { push @{$request}, ($oid_misc64DiskReadBytes, $oid_misc64DiskWriteBytes); } - + my $snmp_result = $options{snmp}->get_leef(oids => $request, nothing_quit => 1); - + $self->{global} = {}; - $self->{global}->{read} = defined($snmp_result->{$oid_misc64DiskReadBytes}) ? - $snmp_result->{$oid_misc64DiskReadBytes} : - ($snmp_result->{$oid_miscHighDiskReadBytes} << 32) + $snmp_result->{$oid_miscLowDiskReadBytes}; - $self->{global}->{write} = defined($snmp_result->{$oid_misc64DiskWriteBytes}) ? - $snmp_result->{$oid_misc64DiskWriteBytes} : - ($snmp_result->{$oid_miscHighDiskWriteBytes} << 32) + $snmp_result->{$oid_miscLowDiskWriteBytes}; + + if (defined($snmp_result->{$oid_misc64DiskReadBytes})) { + $self->{global}->{read} = $snmp_result->{$oid_misc64DiskReadBytes}; + } elsif (defined($snmp_result->{$oid_miscLowDiskReadBytes})) { + $self->{global}->{read} = ($snmp_result->{$oid_miscHighDiskReadBytes} << 32) + $snmp_result->{$oid_miscLowDiskReadBytes}; + } + + if (defined($snmp_result->{$oid_misc64DiskWriteBytes})) { + $self->{global}->{write} = $snmp_result->{$oid_misc64DiskWriteBytes}; + } elsif (defined($snmp_result->{$oid_miscLowDiskWriteBytes})) { + $self->{global}->{write} = ($snmp_result->{$oid_miscHighDiskWriteBytes} << 32) + $snmp_result->{$oid_miscLowDiskWriteBytes}; + } $snmp_result->{$oid_miscGlobalStatusMessage} =~ s/\n//g; - $self->{output}->output_add(severity => ${$states{$snmp_result->{$oid_miscGlobalStatus}}}[1], - short_msg => sprintf("Overall global status is '%s' [message: '%s']", - ${$states{$snmp_result->{$oid_miscGlobalStatus}}}[0], $snmp_result->{$oid_miscGlobalStatusMessage})); - $snmp_result->{$oid_fsStatusMessage} =~ s/\n//g; - $self->{output}->output_add(severity => ${$fs_states{$snmp_result->{$oid_fsOverallStatus}}}[1], - short_msg => sprintf("Overall file system status is '%s' [message: '%s']", - ${$fs_states{$snmp_result->{$oid_fsOverallStatus}}}[0], $snmp_result->{$oid_fsStatusMessage})); + $self->{output}->output_add( + severity => ${$states{$snmp_result->{$oid_miscGlobalStatus}}}[1], + short_msg => sprintf( + "Overall global status is '%s' [message: '%s']", + $states{ $snmp_result->{$oid_miscGlobalStatus} }->[0], $snmp_result->{$oid_miscGlobalStatusMessage} + ) + ); + + if (defined($snmp_result->{$oid_fsStatusMessage})) { + $snmp_result->{$oid_fsStatusMessage} =~ s/\n//g; + $self->{output}->output_add( + severity => ${$fs_states{$snmp_result->{$oid_fsOverallStatus}}}[1], + short_msg => sprintf( + "Overall file system status is '%s' [message: '%s']", + $fs_states{ $snmp_result->{$oid_fsOverallStatus} }->[0], $snmp_result->{$oid_fsStatusMessage} + ) + ); + } $self->{cache_name} = "cache_netapp_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); @@ -138,17 +154,11 @@ If you are in cluster mode, the following mode doesn't work. Ask to netapp to ad =over 8 -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Threshold warning. -Can be: 'read', 'write'. - -=item B<--critical-*> - -Threshold critical. +Thresholds. Can be: 'read', 'write'. =back =cut - From 21d6a31eeeac8e6801ad2227b926ea4d2958cae7 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Wed, 12 Apr 2023 12:01:30 +0200 Subject: [PATCH 380/447] chore(ci): publish releases on download.centreon.com (#4340) Refs: MON-15793 --- .github/actions/release-sources/action.yml | 44 ++++++++++++++++++++++ .github/workflows/plugin-delivery.yml | 34 +++++++++++++++++ .github/workflows/plugins.yml | 3 ++ 3 files changed, 81 insertions(+) create mode 100644 .github/actions/release-sources/action.yml diff --git a/.github/actions/release-sources/action.yml b/.github/actions/release-sources/action.yml new file mode 100644 index 000000000..d414ea676 --- /dev/null +++ b/.github/actions/release-sources/action.yml @@ -0,0 +1,44 @@ +name: "release-sources" +description: "Release sources on download.centreon.com" +inputs: + bucket_directory: + description: The bucket directory + required: true + module_directory: + description: The module directory + required: true + module_name: + description: The module name + required: true + version: + description: The module version + required: true + release: + description: The module release + required: true + token_download_centreon_com: + description: The token to call download.centreon.com api + required: true + +runs: + using: "composite" + steps: + - name: Setup awscli + run: | + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + sudo unzip -q awscliv2.zip + sudo ./aws/install + shell: bash + + - run: | + SRC_FILE="${{ inputs.module_name }}-${{ inputs.version }}.tar.gz" + + mv "${{ inputs.module_directory }}" "${{ inputs.module_name }}-${{ inputs.version }}" + tar czf $SRC_FILE "${{ inputs.module_name }}-${{ inputs.version }}" + + SRC_HASH=$(md5sum $SRC_FILE | cut -d ' ' -f 1) + SRC_SIZE=$(stat -c '%s' $SRC_FILE) + + aws s3 cp --acl public-read "$SRC_FILE" "s3://centreon-download/public/${{ inputs.bucket_directory }}/$SRC_FILE" + curl --fail "https://download.centreon.com/api/?token=${{ inputs.token_download_centreon_com }}&product=${{ inputs.module_name }}&release=${{ inputs.release }}&version=${{ inputs.version }}&extension=tar.gz&md5=$SRC_HASH&size=$SRC_SIZE&ddos=0&dryrun=0" + shell: bash diff --git a/.github/workflows/plugin-delivery.yml b/.github/workflows/plugin-delivery.yml index b01065317..66fbc7541 100644 --- a/.github/workflows/plugin-delivery.yml +++ b/.github/workflows/plugin-delivery.yml @@ -1,6 +1,14 @@ on: workflow_call: inputs: + version: + description: The package version + type: string + required: true + release: + description: The package release + type: string + required: true stability: description: The package stability (stable, testing, unstable) type: string @@ -25,8 +33,34 @@ on: artifactory_token: description: "The artifactory token" required: true + token_download_centreon_com: + description: "The token to call download.centreon.com api" + required: true jobs: + deliver-sources: + runs-on: [self-hosted, common] + if: ${{ contains(fromJson('["stable"]'), inputs.stability) }} + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - uses: actions/cache@v3 + with: + path: ./build/ + key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }} + + - name: Deliver sources + uses: ./.github/actions/release-sources + with: + bucket_directory: centreon-plugins + module_directory: build + module_name: centreon-plugins + version: ${{ inputs.version }} + release: ${{ inputs.release }} + token_download_centreon_com: ${{ secrets.token_download_centreon_com }} + deliver-rpm: runs-on: [self-hosted, common] strategy: diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index ca72b52c8..850d3c166 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -103,6 +103,8 @@ jobs: if: ${{ contains(fromJson('["stable", "testing", "unstable"]'), needs.get-environment.outputs.stability) }} uses: ./.github/workflows/plugin-delivery.yml with: + version: ${{ needs.get-environment.outputs.version }} + release: ${{ needs.get-environment.outputs.release }} stability: ${{ needs.get-environment.outputs.stability }} secrets: nexus_username: ${{ secrets.NEXUS_USERNAME }} @@ -112,3 +114,4 @@ jobs: yum_repo_address: ${{ secrets.YUM_REPO_ADDRESS }} yum_repo_key: ${{ secrets.YUM_REPO_KEY }} artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + token_download_centreon_com: ${{ secrets.TOKEN_DOWNLOAD_CENTREON_COM }} From 877d413ed8cfd1bacb06f20a116e7a5f5d67bd7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Duret?= Date: Thu, 13 Apr 2023 08:55:18 +0200 Subject: [PATCH 381/447] (plugin) os::linux::local - mode pending-updates - add brackets --- src/os/linux/local/mode/pendingupdates.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/linux/local/mode/pendingupdates.pm b/src/os/linux/local/mode/pendingupdates.pm index 3c150b889..e38783791 100644 --- a/src/os/linux/local/mode/pendingupdates.pm +++ b/src/os/linux/local/mode/pendingupdates.pm @@ -104,7 +104,7 @@ sub check_options { ) { $self->{command} = 'yum'; $self->{command_options} = 'check-update 2>&1'; - if defined($self->{option_results}->{check_security}) { + if (defined($self->{option_results}->{check_security})) { $self->{command_options} = '-q updateinfo list sec' } } elsif ($self->{option_results}->{os_mode} eq 'debian') { From 4cb4d2e344f78b3af209d9d287934abf7aa00f20 Mon Sep 17 00:00:00 2001 From: Luth1ng <64541164+Luth1ng@users.noreply.github.com> Date: Fri, 14 Apr 2023 11:16:18 +0400 Subject: [PATCH 382/447] Create alcatel-isam-device-collection.json (#4347) Collection file to check boards status of an Alcatel ISAM 7302 --- .../snmp/alcatel-isam-device-collection.json | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/contrib/collection/snmp/alcatel-isam-device-collection.json diff --git a/src/contrib/collection/snmp/alcatel-isam-device-collection.json b/src/contrib/collection/snmp/alcatel-isam-device-collection.json new file mode 100644 index 000000000..33b0f53c3 --- /dev/null +++ b/src/contrib/collection/snmp/alcatel-isam-device-collection.json @@ -0,0 +1,178 @@ +{ + "mapping": { + "eqptSlotPowerStatus": { + "1": "powerUp", + "2": "powerDown" + }, + "eqptBoardAdminStatus": { + "1": "unlock", + "2": "lock" + }, + "eqptBoardOperStatus": { + "1": "operUp", + "2": "operDown" + }, + "eqptBoardOperError": { + "1": "no-error", + "2": "type-mismatch", + "3": "board-missing", + "4": "board-installation-missing", + "5": "no-planned-board", + "6": "waiting-for-sw", + "7": "init-boot-failed", + "8": "init-download-failed", + "9": "init-connection-failed", + "10": "init-configuration-failed", + "11": "board-reset-protection", + "12": "invalid-parameter", + "13": "temperature-alarm", + "14": "tempshutdown", + "15": "defense", + "16": "board-not-licensed", + "17": "sem-power-fail", + "18": "sem-ups-fail", + "19": "board-in-incompatible-slot", + "21": "download-ongoing", + "255": "unknown-error" + }, + "eqptBoardAvailStatus": { + "1": "available", + "2": "inTest", + "3": "failed", + "4": "powerOff", + "5": "notInstalled", + "6": "offLine", + "7": "dependency" + }, + "eqptBoardRestart": { + "1": "with-selftest", + "2": "without-selftest", + "5": "hot-restart", + "255": "initialValue" + }, + "eqptBoardLastRestartCause": { + "1": "poweron", + "2": "unknown", + "3": "watchdog", + "4": "coldreset", + "5": "warmreset", + "6": "hotreset", + "7": "hotreload", + "8": "cleandata", + "9": "emergencybuild", + "10": "poweronreset", + "11": "commitfailure", + "12": "timezonemodified" + } + }, + "constants": { + "criticalStatus": "operDown" + }, + "snmp": { + "tables": [ + { + "name": "eqptBoardEntry", + "oid": ".1.3.6.1.4.1.637.61.1.23.3.1", + "used_instance": "\\.(\\d+)$", + "entries" :[ + { "name": "eqptSlotPlannedType", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.2" }, + { "name": "eqptSlotActualType", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.3" }, + { "name": "eqptSlotPowerStatus", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.4", "map": "eqptSlotPowerStatus" }, + { "name": "eqptBoardAdminStatus", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.5", "map": "eqptBoardAdminStatus" }, + { "name": "eqptBoardOperStatus", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.6", "map": "eqptBoardOperStatus" }, + { "name": "eqptBoardOperError", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.7", "map": "eqptBoardOperError" }, + { "name": "eqptBoardAvailStatus", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.8", "map": "eqptBoardAvailStatus" }, + { "name": "eqptBoardRestart", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.9", "map": "eqptBoardRestart" }, + { "name": "eqptBoardContainerOffset", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.12" }, + { "name": "eqptBoardInventoryTypeName", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.14" }, + { "name": "eqptBoardInventoryPBACode", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.15" }, + { "name": "eqptBoardInventorySerialNumber", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.19" }, + { "name": "eqptBoardLastRestartCause", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.24", "map": "eqptBoardLastRestartCause" }, + { "name": "eqptBoardLastRestartTime", "oid": ".1.3.6.1.4.1.637.61.1.23.3.1.25" } + ] + } + ] + + }, + "selection": [ + { + "name": "operUp", + "functions": [ + { + "type": "count", + "src": "%(snmp.tables.eqptBoardEntry)", + "filter": "%(src.eqptBoardOperStatus) eq %(name)", + "save": "%(numOperUp)" + } + ], + "perfdatas": [ + { + "nlabel": "isam.device.%(name).count", + "value": "%(numOperUp)", + "min": 0 + + } + ], + "formatting": { + "printf_msg": "Number of %s device: %d", + "printf_var": [ + "%(name)", + "%(numOperUp)" + ], + "display_ok": false + } + }, + { + "name": "operDown", + "functions": [ + { + "type": "count", + "src": "%(snmp.tables.eqptBoardEntry)", + "filter": "%(src.eqptBoardOperStatus) eq %(name)", + "save": "%(numOperDown)" + } + ], + "perfdatas": [ + { + "nlabel": "isam.device.%(name).count", + "value": "%(numOperDown)", + "min": 0 + + } + ], + "formatting": { + "printf_msg": "Number of %s device: %d", + "printf_var": [ + "%(name)", + "%(numOperDown)" + ], + "display_ok": false + } + } + ], + "selection_loop": [ + { + "name": "eqptSlot ISAM", + "source": "%(snmp.tables.eqptBoardEntry)", + "expand_table": { + "eqptBoardEntry": "%(snmp.tables.eqptBoardEntry.[%(eqptBoardEntry.instance)])" + }, + "critical": "%(eqptBoardEntry.eqptBoardOperStatus) =~ /%(constants.criticalStatus)/", + "formatting": { + "printf_msg": "Card %s (slot%s): status is %s (%s), power status is %s", + "printf_var": [ + "%(eqptBoardEntry.eqptSlotActualType)", + "%(eqptBoardEntry.eqptBoardContainerOffset)", + "%(eqptBoardEntry.eqptBoardOperStatus)", + "%(eqptBoardEntry.eqptBoardOperError)", + "%(eqptBoardEntry.eqptSlotPowerStatus)" + ], + "display_ok": true + } + } + ], + "formatting": { + "custom_message_global": "All ISAM Boards are OK", + "separator": "-" + } +} From e4ad6f82366ef9f90d605fa140f3f177b5daeda5 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 14 Apr 2023 11:46:58 +0200 Subject: [PATCH 383/447] (plugin) apps::backup::commvault::commserve::restapi - mode jobs change limit (#4351) --- src/apps/backup/commvault/commserve/restapi/custom/api.pm | 4 +++- src/apps/backup/commvault/commserve/restapi/mode/jobs.pm | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/apps/backup/commvault/commserve/restapi/custom/api.pm b/src/apps/backup/commvault/commserve/restapi/custom/api.pm index 6702b84ff..127934ee4 100644 --- a/src/apps/backup/commvault/commserve/restapi/custom/api.pm +++ b/src/apps/backup/commvault/commserve/restapi/custom/api.pm @@ -236,6 +236,7 @@ sub request_internal { my $content = $self->{http}->request( url_path => $self->{url_path} . $options{endpoint}, get_param => $options{get_param}, + header => $options{header}, warning_status => '', unknown_status => '', critical_status => '' @@ -337,7 +338,8 @@ sub request_jobs { my $response = $self->request_internal( endpoint => $options{endpoint}, - get_param => ['completedJobLookupTime=' . $lookup_time] + get_param => ['completedJobLookupTime=' . $lookup_time], + header => ['limit: 10000'] ); $self->create_cache_file(type => 'jobs', response => $response) diff --git a/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm b/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm index 706540558..2b1b7cfde 100644 --- a/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm +++ b/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm @@ -199,9 +199,9 @@ sub manage_selection { $self->{output}->output_add(long_msg => "skipping job '" . $policy_name . "/" . $job->{jobId} . "': no matching filter type.", debug => 1); next; } - if (defined($job->{clientGroups}) && defined($self->{option_results}->{filter_client_name}) && $self->{option_results}->{filter_client_name} ne '') { + if (defined($self->{option_results}->{filter_client_group}) && $self->{option_results}->{filter_client_group} ne '' && defined($job->{clientGroups}) && ref($job->{clientGroups}) eq 'ARRAY') { my $matched = 0; - foreach (@$job->{clientGroups}) { + foreach (@{$job->{clientGroups}}) { if ($_->{clientGroupName} =~ /$self->{option_results}->{filter_client_group}/) { $matched = 1; last; From c2a22ae09eb1c9d5ff4c954ef085dea1253d84cf Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 18 Apr 2023 09:28:01 +0200 Subject: [PATCH 384/447] (plugin) apps::controlm::restapi - mode jobs add option --display-extra-attrs (#4360) --- src/apps/controlm/restapi/mode/jobs.pm | 36 +++++++++++++++++++------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/apps/controlm/restapi/mode/jobs.pm b/src/apps/controlm/restapi/mode/jobs.pm index be7957f48..20ca5072d 100644 --- a/src/apps/controlm/restapi/mode/jobs.pm +++ b/src/apps/controlm/restapi/mode/jobs.pm @@ -32,7 +32,11 @@ use DateTime; sub custom_status_output { my ($self, %options) = @_; - return 'status: ' . $self->{result_values}->{status}; + my $msg = 'status: ' . $self->{result_values}->{status}; + if ($self->{result_values}->{extra_attrs} ne '') { + $msg .= $self->{result_values}->{extra_attrs}; + } + return $msg; } sub custom_long_output { @@ -86,7 +90,7 @@ sub set_counters { set => { key_values => [ { name => 'status' }, { name => 'name' }, { name => 'application' }, - { name => 'type' }, { name => 'folder' }, + { name => 'type' }, { name => 'folder' }, { name => 'extra_attrs' } ], closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, @@ -155,12 +159,13 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - 'filter-application:s' => { name => 'filter_application' }, - 'filter-folder:s' => { name => 'filter_folder' }, - 'filter-type:s' => { name => 'filter_type' }, - 'filter-name:s' => { name => 'filter_name' }, - 'job-name:s' => { name => 'job_name' }, - 'timezone:s' => { name => 'timezone' } + 'filter-application:s' => { name => 'filter_application' }, + 'filter-folder:s' => { name => 'filter_folder' }, + 'filter-type:s' => { name => 'filter_type' }, + 'filter-name:s' => { name => 'filter_name' }, + 'display-extra-attrs:s' => { name => 'display_extra_attrs' }, + 'job-name:s' => { name => 'job_name' }, + 'timezone:s' => { name => 'timezone' } }); return $self; @@ -231,6 +236,14 @@ sub manage_selection { # Wait Condition — waiting for a condition. $self->{global}->{waiting}++; } + + my $extra_attrs = ''; + if (defined($self->{option_results}->{display_extra_attrs}) && $self->{option_results}->{display_extra_attrs} ne '') { + $extra_attrs = $self->{option_results}->{display_extra_attrs}; + $extra_attrs =~ s/%\{(.*?)\}/$job->{$1}/g; + $extra_attrs =~ s/%\((.*?)\)/$job->{$1}/g; + } + $self->{jobs}->{ $job->{jobId} } = { name => $job->{name}, folder => $job->{folder}, @@ -238,7 +251,8 @@ sub manage_selection { type => $job->{type}, status => lc($job->{status}), elapsed => $elapsed, - failed => $failed + failed => $failed, + extra_attrs => $extra_attrs }; } } @@ -278,6 +292,10 @@ Filter jobs by job name (can be a regexp). Check exact job name (no regexp). +=item B<--display-extra-attrs> + +Display extra job attributes (Eg: --display-extra-attrs=', number of runs: %(numberOfRuns)'). + =item B<--timezone> Set date timezone. From 43e63fb4acbd19d54cf45c0125de3afd4872ae8b Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 18 Apr 2023 13:58:31 +0200 Subject: [PATCH 385/447] (plugin) apps::protocols::dns - option --nameservers can use coma (#4362) --- src/apps/protocols/dns/lib/dns.pm | 11 ++++++++++- src/apps/protocols/dns/mode/request.pm | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/apps/protocols/dns/lib/dns.pm b/src/apps/protocols/dns/lib/dns.pm index d527e5756..18b0af82a 100644 --- a/src/apps/protocols/dns/lib/dns.pm +++ b/src/apps/protocols/dns/lib/dns.pm @@ -77,11 +77,20 @@ sub connect { my %dns_options = (); if (defined($self->{option_results}->{nameservers})) { - $dns_options{nameservers} = [@{$self->{option_results}->{nameservers}}]; + foreach my $ns (@{$self->{option_results}->{nameservers}}) { + my @entries = split(/,/, $ns); + foreach my $name (@entries) { + next if ($name eq ''); + $dns_options{nameservers} = [] if (!defined($dns_options{nameservers})); + push @{$dns_options{nameservers}}, $name; + } + } } + if (defined($self->{option_results}->{searchlist})) { $dns_options{searchlist} = [@{$self->{option_results}->{searchlist}}]; } + foreach my $option (@{$self->{option_results}->{dns_options}}) { next if ($option !~ /^(.+?)=(.+)$/); $dns_options{$1} = $2; diff --git a/src/apps/protocols/dns/mode/request.pm b/src/apps/protocols/dns/mode/request.pm index 92f375a63..858f31061 100644 --- a/src/apps/protocols/dns/mode/request.pm +++ b/src/apps/protocols/dns/mode/request.pm @@ -163,7 +163,7 @@ perl centreon_plugins.pl --plugin=apps::protocols::dns::plugin --mode=request -- =item B<--nameservers> -Set nameserver to query (can be multiple). +Set nameserver to query (can use option multiple times or separated values by coma). The system configuration is used by default. =item B<--searchlist> From 9665ea68c4e8d3f6fb8852b8c4a813a0b9fb2b5f Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 18 Apr 2023 14:10:11 +0200 Subject: [PATCH 386/447] =?UTF-8?q?(plugin)=20hardware::server::hp::ilo::r?= =?UTF-8?q?estapi=20-=20mode=20hardware=20ignore=20som=E2=80=A6=20(#4349)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/redfish/restapi/mode/hardware.pm | 14 ++++++++++++-- src/hardware/server/hp/ilo/restapi/custom/api.pm | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/centreon/common/redfish/restapi/mode/hardware.pm b/src/centreon/common/redfish/restapi/mode/hardware.pm index ea838db72..348d5e6e6 100644 --- a/src/centreon/common/redfish/restapi/mode/hardware.pm +++ b/src/centreon/common/redfish/restapi/mode/hardware.pm @@ -84,7 +84,12 @@ sub get_devices { $self->get_chassis() if (!defined($self->{chassis})); foreach my $chassis (@{$self->{chassis}}) { $chassis->{Devices} = []; - my $result = $self->{custom}->request_api(url_path => $chassis->{'@odata.id'} . 'Devices/'); + my $result = $self->{custom}->request_api( + url_path => $chassis->{'@odata.id'} . 'Devices/', + ignore_codes => { 404 => 1 } + ); + next if (!defined($result)); + foreach (@{$result->{Members}}) { my $device_detailed = $self->{custom}->request_api(url_path => $_->{'@odata.id'}); push @{$chassis->{Devices}}, $device_detailed; @@ -135,7 +140,12 @@ sub get_storages { $self->{storages} = []; my $systems = $self->{custom}->request_api(url_path => '/redfish/v1/Systems'); foreach my $system (@{$systems->{Members}}) { - my $storages = $self->{custom}->request_api(url_path => $system->{'@odata.id'} . '/Storage/'); + my $storages = $self->{custom}->request_api( + url_path => $system->{'@odata.id'} . '/Storage/', + ignore_codes => { 400 => 1, 404 => 1 } + ); + next if (!defined($storages)); + foreach my $storage (@{$storages->{Members}}) { my $storage_detailed = $self->{custom}->request_api(url_path => $storage->{'@odata.id'}); push @{$self->{storages}}, $storage_detailed; diff --git a/src/hardware/server/hp/ilo/restapi/custom/api.pm b/src/hardware/server/hp/ilo/restapi/custom/api.pm index f8523a0f2..0af66d642 100644 --- a/src/hardware/server/hp/ilo/restapi/custom/api.pm +++ b/src/hardware/server/hp/ilo/restapi/custom/api.pm @@ -191,26 +191,34 @@ sub request_api { $self->authenticate(statefile => $self->{cache}); } - my $content = $self->{http}->request(%options, + my $content = $self->{http}->request( + %options, warning_status => '', unknown_status => '', critical_status => '' ); + my $code = $self->{http}->get_code(); + return undef if (defined($options{ignore_codes}) && defined($options{ignore_codes}->{$code})); + # Maybe there is an issue with the token. So we retry. - if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { + if ($code < 200 || $code >= 300) { $self->clean_token(statefile => $self->{cache}); $self->authenticate(statefile => $self->{cache}); - $content = $self->{http}->request(%options, + $content = $self->{http}->request( + %options, warning_status => '', unknown_status => '', critical_status => '' ); + $code = $self->{http}->get_code(); } + return undef if (defined($options{ignore_codes}) && defined($options{ignore_codes}->{$code})); + my $decoded = $self->json_decode(content => $content); if (!defined($decoded)) { $self->{output}->add_option_msg(short_msg => "Error while retrieving data (add --debug option for detailed message)"); $self->{output}->option_exit(); } - if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { + if ($code < 200 || $code >= 300) { $self->{output}->add_option_msg(short_msg => 'api request error: ' . (defined($decoded->{type}) ? $decoded->{type} : 'unknown')); $self->{output}->option_exit(); } From 69737a11dde525419bcb6e18aaa35dd7ce1f3df9 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 18 Apr 2023 14:12:55 +0200 Subject: [PATCH 387/447] (plugin) cloud::outscale - new (#4350) --- .../deb.json | 5 + .../pkg.json | 9 + .../rpm.json | 5 + src/cloud/outscale/custom/http.pm | 403 +++++++++++++++ src/cloud/outscale/custom/osccli.pm | 468 ++++++++++++++++++ .../outscale/mode/accountconsumptions.pm | 204 ++++++++ src/cloud/outscale/mode/clientgateways.pm | 198 ++++++++ src/cloud/outscale/mode/internetservices.pm | 174 +++++++ src/cloud/outscale/mode/listclientgateways.pm | 122 +++++ .../outscale/mode/listinternetservices.pm | 122 +++++ src/cloud/outscale/mode/listloadbalancers.pm | 107 ++++ src/cloud/outscale/mode/listnatservices.pm | 122 +++++ src/cloud/outscale/mode/listnets.pm | 122 +++++ src/cloud/outscale/mode/listquotas.pm | 107 ++++ src/cloud/outscale/mode/listroutetables.pm | 106 ++++ src/cloud/outscale/mode/listsubnets.pm | 122 +++++ .../outscale/mode/listvirtualgateways.pm | 122 +++++ src/cloud/outscale/mode/listvms.pm | 122 +++++ src/cloud/outscale/mode/listvolumes.pm | 109 ++++ src/cloud/outscale/mode/listvpnconnections.pm | 122 +++++ src/cloud/outscale/mode/loadbalancers.pm | 225 +++++++++ src/cloud/outscale/mode/natservices.pm | 175 +++++++ src/cloud/outscale/mode/nets.pm | 168 +++++++ src/cloud/outscale/mode/quotas.pm | 200 ++++++++ src/cloud/outscale/mode/routetables.pm | 127 +++++ src/cloud/outscale/mode/subnets.pm | 213 ++++++++ src/cloud/outscale/mode/virtualgateways.pm | 198 ++++++++ src/cloud/outscale/mode/vms.pm | 175 +++++++ src/cloud/outscale/mode/volumes.pm | 218 ++++++++ src/cloud/outscale/mode/vpnconnections.pm | 215 ++++++++ src/cloud/outscale/plugin.pm | 73 +++ 31 files changed, 4858 insertions(+) create mode 100644 packaging/centreon-plugin-Cloud-Outscale-Api/deb.json create mode 100644 packaging/centreon-plugin-Cloud-Outscale-Api/pkg.json create mode 100644 packaging/centreon-plugin-Cloud-Outscale-Api/rpm.json create mode 100644 src/cloud/outscale/custom/http.pm create mode 100644 src/cloud/outscale/custom/osccli.pm create mode 100644 src/cloud/outscale/mode/accountconsumptions.pm create mode 100644 src/cloud/outscale/mode/clientgateways.pm create mode 100644 src/cloud/outscale/mode/internetservices.pm create mode 100644 src/cloud/outscale/mode/listclientgateways.pm create mode 100644 src/cloud/outscale/mode/listinternetservices.pm create mode 100644 src/cloud/outscale/mode/listloadbalancers.pm create mode 100644 src/cloud/outscale/mode/listnatservices.pm create mode 100644 src/cloud/outscale/mode/listnets.pm create mode 100644 src/cloud/outscale/mode/listquotas.pm create mode 100644 src/cloud/outscale/mode/listroutetables.pm create mode 100644 src/cloud/outscale/mode/listsubnets.pm create mode 100644 src/cloud/outscale/mode/listvirtualgateways.pm create mode 100644 src/cloud/outscale/mode/listvms.pm create mode 100644 src/cloud/outscale/mode/listvolumes.pm create mode 100644 src/cloud/outscale/mode/listvpnconnections.pm create mode 100644 src/cloud/outscale/mode/loadbalancers.pm create mode 100644 src/cloud/outscale/mode/natservices.pm create mode 100644 src/cloud/outscale/mode/nets.pm create mode 100644 src/cloud/outscale/mode/quotas.pm create mode 100644 src/cloud/outscale/mode/routetables.pm create mode 100644 src/cloud/outscale/mode/subnets.pm create mode 100644 src/cloud/outscale/mode/virtualgateways.pm create mode 100644 src/cloud/outscale/mode/vms.pm create mode 100644 src/cloud/outscale/mode/volumes.pm create mode 100644 src/cloud/outscale/mode/vpnconnections.pm create mode 100644 src/cloud/outscale/plugin.pm diff --git a/packaging/centreon-plugin-Cloud-Outscale-Api/deb.json b/packaging/centreon-plugin-Cloud-Outscale-Api/deb.json new file mode 100644 index 000000000..8133a85e5 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Outscale-Api/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libdatetime-perl" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Outscale-Api/pkg.json b/packaging/centreon-plugin-Cloud-Outscale-Api/pkg.json new file mode 100644 index 000000000..98f2bcbed --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Outscale-Api/pkg.json @@ -0,0 +1,9 @@ +{ + "pkg_name": "centreon-plugin-Cloud-Outscale-Api", + "pkg_summary": "Centreon Plugin to monitor Outscale using API", + "plugin_name": "centreon_outscale_api.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "cloud/outscale/" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Outscale-Api/rpm.json b/packaging/centreon-plugin-Cloud-Outscale-Api/rpm.json new file mode 100644 index 000000000..e9dff7552 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Outscale-Api/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(DateTime)" + ] +} diff --git a/src/cloud/outscale/custom/http.pm b/src/cloud/outscale/custom/http.pm new file mode 100644 index 000000000..012100aaf --- /dev/null +++ b/src/cloud/outscale/custom/http.pm @@ -0,0 +1,403 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::custom::http; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'osc-secret-key:s' => { name => 'osc_secret_key' }, + 'osc-access-key:s' => { name => 'osc_access_key' }, + 'region:s' => { name => 'region' }, + 'port:s' => { name => 'port' }, + 'proto:s' => { name => 'proto' }, + 'timeout:s' => { name => 'timeout' }, + 'api-path:s' => { name => 'api_path' }, + 'unknown-http-status:s' => { name => 'unknown_http_status' }, + 'warning-http-status:s' => { name => 'warning_http_status' }, + 'critical-http-status:s' => { name => 'critical_http_status' } + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl'); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 50; + $self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300'; + $self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : ''; + $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : ''; + $self->{api_path} = (defined($self->{option_results}->{api_path})) ? $self->{option_results}->{api_path} : '/api/v1'; + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{osc_access_key}) || $self->{option_results}->{osc_access_key} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --osc-access-key option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{osc_secret_key}) || $self->{option_results}->{osc_secret_key} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --osc-secret-key option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; +} + +sub settings { + my ($self, %options) = @_; + + return if (defined($self->{settings_done})); + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->set_options(%{$self->{option_results}}); + $self->{settings_done} = 1; +} + +sub request_api { + my ($self, %options) = @_; + + $self->settings(); + my $content = $self->{http}->request( + hostname => 'api.' . $self->{option_results}->{region} . '.outscale.com', + method => $options{method}, + url_path => $self->{api_path} . $options{endpoint}, + get_param => $options{get_param}, + header => $options{header}, + query_form_post => $options{query_form_post}, + credentials => 1, + username => $self->{option_results}->{osc_access_key}, + password => $self->{option_results}->{osc_secret_key}, + curl_opt => ["CURLOPT_AWS_SIGV4 => 'osc'"], + unknown_status => $self->{unknown_http_status}, + warning_status => $self->{warning_http_status}, + critical_status => $self->{critical_http_status} + ); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub load_balancer_read { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadLoadBalancers', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{LoadBalancers}; +} + +sub read_vms_health { + my ($self, %options) = @_; + + my $post; + eval { + $post = JSON::XS->new->utf8->encode({ LoadBalancerName => $options{load_balancer_name} }); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => 'cannot encode json request'); + $self->{output}->option_exit(); + } + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadVmsHealth', + header => ['Content-Type: application/json'], + query_form_post => $post + ); + + return $raw_results->{BackendVmHealth}; +} + +sub read_vms { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadVms', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{Vms}; +} + +sub read_client_gateways { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadClientGateways', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{ClientGateways}; +} + +sub read_consumption_account { + my ($self, %options) = @_; + + my $post; + eval { + $post = JSON::XS->new->utf8->encode({ FromDate => $options{from_date}, ToDate => $options{to_date} }); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => 'cannot encode json request'); + $self->{output}->option_exit(); + } + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadConsumptionAccount', + header => ['Content-Type: application/json'], + query_form_post => $post + ); + + return $raw_results->{ConsumptionEntries}; +} + +sub read_virtual_gateways { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadVirtualGateways', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{VirtualGateways}; +} + +sub read_vpn_connections { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadVpnConnections', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{VpnConnections}; +} + +sub read_volumes { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadVolumes', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{Volumes}; +} + +sub read_nets { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadNets', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{Nets}; +} + +sub read_quotas { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadQuotas', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{QuotaTypes}; +} + +sub read_subnets { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadSubnets', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{Subnets}; +} + +sub read_route_tables { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadRouteTables', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{RouteTables}; +} + +sub read_internet_services { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadInternetServices', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{InternetServices}; +} + +sub read_nat_services { + my ($self, %options) = @_; + + my $raw_results = $self->request_api( + method => 'POST', + endpoint => '/ReadNatServices', + header => ['Content-Type: application/json'], + query_form_post => '' + ); + + return $raw_results->{NatServices}; +} + +1; + +__END__ + +=head1 NAME + +Outscale Rest API + +=head1 REST API OPTIONS + +Outscale Rest API + +=over 8 + +=item B<--osc-secret-key> + +Set Outscale secret key. + +=item B<--osc-access-key> + +Set Outscale access key. + +=item B<--region> + +Set the region name (Required). + +=item B<--port> + +Port used (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--token> + +API token. + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/src/cloud/outscale/custom/osccli.pm b/src/cloud/outscale/custom/osccli.pm new file mode 100644 index 000000000..adb43e4e1 --- /dev/null +++ b/src/cloud/outscale/custom/osccli.pm @@ -0,0 +1,468 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::custom::osccli; + +use strict; +use warnings; +use centreon::plugins::misc; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'profile:s' => { name => 'profile' }, + 'virtual-env:s' => { name => 'virtual_env' }, + 'timeout:s' => { name => 'timeout', default => 50 }, + 'sudo' => { name => 'sudo' }, + 'command:s' => { name => 'command' }, + 'command-path:s' => { name => 'command_path' }, + 'command-options:s' => { name => 'command_options' }, + 'proxyurl:s' => { name => 'proxyurl' } + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'OSCCLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{custommode_name} = $options{custommode_name}; + + return $self; +} + +sub get_region { + my ($self, %options) = @_; + + return $self->{option_results}->{region}; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{proxyurl}) && $self->{option_results}->{proxyurl} ne '') { + $ENV{HTTP_PROXY} = $self->{option_results}->{proxyurl}; + $ENV{HTTPS_PROXY} = $self->{option_results}->{proxyurl}; + } + + if (defined($self->{option_results}->{virtual_env}) && $self->{option_results}->{virtual_env} ne '') { + $ENV{VIRTUAL_ENV} = $self->{option_results}->{virtual_env}; + $ENV{PATH} = "$ENV{VIRTUAL_ENV}/bin:$ENV{PATH}"; + } + + centreon::plugins::misc::check_security_command( + output => $self->{output}, + command => $self->{option_results}->{command}, + command_options => $self->{option_results}->{command_options}, + command_path => $self->{option_results}->{command_path} + ); + + return 0; +} + +sub execute { + my ($self, %options) = @_; + + my $command = defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : 'osc-cli'; + + my $cmd_options = $options{cmd_options}; + + $self->{output}->output_add(long_msg => "Command line: '" . $command . " " . $cmd_options . "'", debug => 1); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $command, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options, + redirect_stderr => ($self->{output}->is_debug()) ? 0 : 1 + ); + + my $raw_results = {}; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub load_balancer_read_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadLoadBalancers'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub load_balancer_read { + my ($self, %options) = @_; + + my $cmd_options = $self->load_balancer_read_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{LoadBalancers}; +} + +sub read_vms_health_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadVmsHealth'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + $cmd_options .= " --LoadBalancerName '$options{load_balancer_name}'"; + + return $cmd_options; +} + +sub read_vms_health { + my ($self, %options) = @_; + + my $cmd_options = $self->read_vms_health_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{BackendVmHealth}; +} + +sub read_vms_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadVms'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_vms { + my ($self, %options) = @_; + + my $cmd_options = $self->read_vms_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{Vms}; +} + +sub read_client_gateways_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadClientGateways'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_client_gateways { + my ($self, %options) = @_; + + my $cmd_options = $self->read_client_gateways_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{ClientGateways}; +} + +sub read_consumption_account_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadConsumptionAccount'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + $cmd_options .= " --FromDate '$options{from_date}' --ToDate '$options{to_date}'"; + + return $cmd_options; +} + +sub read_consumption_account { + my ($self, %options) = @_; + + my $cmd_options = $self->read_consumption_account_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{ConsumptionEntries}; +} + +sub read_virtual_gateways_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadVirtualGateways'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_virtual_gateways { + my ($self, %options) = @_; + + my $cmd_options = $self->read_virtual_gateways_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{VirtualGateways}; +} + +sub read_vpn_connections_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadVpnConnections'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_vpn_connections { + my ($self, %options) = @_; + + my $cmd_options = $self->read_vpn_connections_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{VpnConnections}; +} + +sub read_volumes_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadVolumes'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_volumes { + my ($self, %options) = @_; + + my $cmd_options = $self->read_volumes_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{Volumes}; +} + +sub read_nets_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadNets'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_nets { + my ($self, %options) = @_; + + my $cmd_options = $self->read_nets_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{Nets}; +} + +sub read_quotas_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadQuotas'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_quotas { + my ($self, %options) = @_; + + my $cmd_options = $self->read_quotas_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{QuotaTypes}; +} + +sub read_subnets_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadSubnets'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_subnets { + my ($self, %options) = @_; + + my $cmd_options = $self->read_subnets_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{Subnets}; +} + +sub read_route_tables_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadRouteTables'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_route_tables { + my ($self, %options) = @_; + + my $cmd_options = $self->read_route_tables_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{RouteTables}; +} + +sub read_internet_services_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadInternetServices'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_internet_services { + my ($self, %options) = @_; + + my $cmd_options = $self->read_internet_services_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{InternetServices}; +} + +sub read_nat_services_set_cmd { + my ($self, %options) = @_; + + return $self->{option_results}->{command_options} if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = 'api ReadNatServices'; + $cmd_options .= " --profile '$self->{option_results}->{profile}'" if (defined($self->{option_results}->{profile}) && $self->{option_results}->{profile} ne ''); + + return $cmd_options; +} + +sub read_nat_services { + my ($self, %options) = @_; + + my $cmd_options = $self->read_nat_services_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results->{NatServices}; +} + +1; + +__END__ + +=head1 NAME + +Outscale + +=head1 OSCCLI OPTIONS + +Outscale CLI + +=over 8 + +=item B<--profile> + +Set profile option. + +=item B<--virtual-env> + +Set python virtual environment (to be used if osc-cli is installed in python venv). + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'osc-cli'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). +Only use for testing purpose, when you want to set ALL parameters of a command by yourself. + +=item B<--proxyurl> + +Proxy URL if any + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/src/cloud/outscale/mode/accountconsumptions.pm b/src/cloud/outscale/mode/accountconsumptions.pm new file mode 100644 index 000000000..1bcedf9c0 --- /dev/null +++ b/src/cloud/outscale/mode/accountconsumptions.pm @@ -0,0 +1,204 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::accountconsumptions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use DateTime; + +sub consumption_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking account consumption '%s' [service: %s] [region: %s]", + $options{instance_value}->{title}, + $options{instance_value}->{service}, + $options{instance_value}->{region} + ); +} + +sub prefix_consumption_output { + my ($self, %options) = @_; + + return sprintf( + "account consumption '%s' [service: %s] [region: %s] ", + $options{instance_value}->{title}, + $options{instance_value}->{service}, + $options{instance_value}->{region} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of account consumptions '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { + name => 'consumptions', type => 3, cb_prefix_output => 'prefix_consumption_output', cb_long_output => 'consumption_long_output', indent_long_output => ' ', message_multiple => 'All account consumptions are ok', + group => [ + { name => 'metrics', type => 0 } + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'account-consumptions-detected', display_ok => 0, nlabel => 'account.consumptions.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{metrics} = [ + { label => 'account-consumption', nlabel => 'accounts.consumption.count', set => { + key_values => [ { name => 'value' }, { name => 'title' }, { name => 'service' }, { name => 'region' } ], + output_template => 'value: %.3f', + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => [$self->{result_values}->{title}, $self->{result_values}->{service}, $self->{result_values}->{region}], + value => sprintf('%.3f', $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}) + ); + } + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-region:s' => { name => 'filter_region' }, + 'filter-service:s' => { name => 'filter_service' }, + 'filter-category:s' => { name => 'filter_category' }, + 'filter-title:s' => { name => 'filter_title' }, + 'timeframe:s' => { name => 'timeframe' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{timeframe}) || $self->{option_results}->{timeframe} !~ /\d/) { + $self->{option_results}->{timeframe} = 1; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $dt = DateTime->now(time_zone => 'UTC'); + my $to_date = sprintf('%02d-%02d-%02d', $dt->year(), $dt->month(), $dt->day()); + $dt->subtract(days => $self->{option_results}->{timeframe}); + my $from_date = sprintf('%02d-%02d-%02d', $dt->year(), $dt->month(), $dt->day()); + + my $consumptions = $options{custom}->read_consumption_account(from_date => $from_date, to_date => $to_date); + + $self->{global} = { detected => 0 }; + $self->{consumptions} = {}; + + my $i = 0; + foreach (@$consumptions) { + next if (defined($self->{option_results}->{filter_region}) && $self->{option_results}->{filter_region} ne '' && + $_->{SubregionName} !~ /$self->{option_results}->{filter_region}/); + next if (defined($self->{option_results}->{filter_service}) && $self->{option_results}->{filter_service} ne '' && + $_->{Service} !~ /$self->{option_results}->{filter_service}/); + next if (defined($self->{option_results}->{filter_category}) && $self->{option_results}->{filter_category} ne '' && + $_->{Category} !~ /$self->{option_results}->{filter_category}/); + next if (defined($self->{option_results}->{filter_title}) && $self->{option_results}->{filter_title} ne '' && + $_->{Title} !~ /$self->{option_results}->{filter_title}/); + + $self->{consumptions}->{$i} = { + title => $_->{Title}, + service => $_->{Service}, + region => $_->{SubregionName}, + metrics => { + title => $_->{Title}, + service => $_->{Service}, + region => $_->{SubregionName}, + value => $_->{Value} + } + }; + $i++; + + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check account consumptions. + +=over 8 + +=item B<--filter-title> + +Filter account consumptions by title. + +=item B<--filter-service> + +Filter account consumptions by service. + +=item B<--filter-category> + +Filter account consumptions by category. + +=item B<--filter-region> + +Filter account consumptions by region. + +=item B<--timeframe> + +Set timeframe in days (Default: 1). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'account-consumptions-detected', 'account-consumption'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/clientgateways.pm b/src/cloud/outscale/mode/clientgateways.pm new file mode 100644 index 000000000..6652e5891 --- /dev/null +++ b/src/cloud/outscale/mode/clientgateways.pm @@ -0,0 +1,198 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::clientgateways; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_cg_output { + my ($self, %options) = @_; + + return sprintf( + "client gateway '%s' ", + $options{instance_value}->{cgName} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of client gateways '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'cgs', type => 1, cb_prefix_output => 'prefix_cg_output', message_multiple => 'All client gateways are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'cgs-detected', display_ok => 0, nlabel => 'client_gateways.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'cgs-available', display_ok => 0, nlabel => 'client_gateways.available.count', set => { + key_values => [ { name => 'available' } ], + output_template => 'available: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'cgs-pending', display_ok => 0, nlabel => 'client_gateways.pending.count', set => { + key_values => [ { name => 'pending' } ], + output_template => 'pending: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'cgs-deleting', display_ok => 0, nlabel => 'client_gateways.deleting.count', set => { + key_values => [ { name => 'deleting' } ], + output_template => 'deleting: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'cgs-deleted', display_ok => 0, nlabel => 'client_gateways.deleted.count', set => { + key_values => [ { name => 'deleted' } ], + output_template => 'deleted: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{cgs} = [ + { + label => 'cg-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'cgName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'cg-tag-name:s' => { name => 'cg_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_cg_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{cg_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $cgs = $options{custom}->read_client_gateways(); + + $self->{global} = { detected => 0, available => 0, pending => 0, deleting => 0, deleted => 0 }; + $self->{cgs} = {}; + + foreach my $cg (@$cgs) { + my $name = $self->get_cg_name(tags => $cg->{Tags}, id => $cg->{ClientGatewayId}); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{cgs}->{$name} = { + cgName => $name, + state => lc($cg->{State}) + }; + + $self->{global}->{ lc($cg->{State}) }++ + if (defined($self->{global}->{ lc($cg->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check client gateways. + +=over 8 + +=item B<--filter-name> + +Filter client gateways by name. + +=item B<--cg-tag-name> + +Client gateway tags to be used for the name (Default: 'name'). + +=item B<--unknown-cg-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{cgName} + +=item B<--warning-cg-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{cgName} + +=item B<--critical-cg-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{cgName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'cgs-detected', 'cgs-available', 'cgs-pending', +'cgs-deleting', 'cgs-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/internetservices.pm b/src/cloud/outscale/mode/internetservices.pm new file mode 100644 index 000000000..9f2a50e8c --- /dev/null +++ b/src/cloud/outscale/mode/internetservices.pm @@ -0,0 +1,174 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::internetservices; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_service_output { + my ($self, %options) = @_; + + return sprintf( + "internet service '%s' ", + $options{instance_value}->{internetServiceName} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of internet services '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'services', type => 1, cb_prefix_output => 'prefix_service_output', message_multiple => 'All internet services are ok' } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('detected', 'available') { + push @{$self->{maps_counters}->{global}}, { + label => 'internet-services-' . $_, display_ok => 0, nlabel => 'internet_services.' . $_ . '.count', set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{services} = [ + { + label => 'internet-service-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'internetServiceName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-id:s' => { name => 'filter_id' }, + 'filter-name:s' => { name => 'filter_name' }, + 'internet-service-tag-name:s' => { name => 'internet_service_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_internet_service_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{internet_service_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $services = $options{custom}->read_internet_services(); + + $self->{global} = { detected => 0, available => 0 }; + $self->{services} = {}; + + foreach (@$services) { + my $name = $self->get_internet_service_name(tags => $_->{Tags}, id => $_->{InternetServiceId}); + + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $_->{InternetServiceId} !~ /$self->{option_results}->{filter_id}/); + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{services}->{ $_->{InternetServiceId} } = { + internetServiceName => $name, + state => lc($_->{State}) + }; + + $self->{global}->{ lc($_->{State}) }++ + if (defined($self->{global}->{ lc($_->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check internet services. + +=over 8 + +=item B<--filter-id> + +Filter internet services by id. + +=item B<--filter-name> + +Filter internet services by name. + +=item B<--internet-service-tag-name> + +Internet service tag to be used for the name (Default: 'name'). + +=item B<--unknown-internet-service-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{internetServiceName} + +=item B<--warning-internet-service-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{internetServiceName} + +=item B<--critical-internet-service-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{internetServiceName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'internet-services-detected', 'internet-services-available'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/listclientgateways.pm b/src/cloud/outscale/mode/listclientgateways.pm new file mode 100644 index 000000000..7268e2f66 --- /dev/null +++ b/src/cloud/outscale/mode/listclientgateways.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listclientgateways; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'cg-tag-name:s' => { name => 'cg_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_cg_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{cg_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $cgs = $options{custom}->read_client_gateways(); + + my $results = {}; + foreach (@$cgs) { + my $name = $self->get_cg_name(tags => $_->{Tags}, id => $_->{ClientGatewayId}); + + $results->{$name} = { + id => $_->{ClientGatewayId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List client gateways:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List client gateways. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listinternetservices.pm b/src/cloud/outscale/mode/listinternetservices.pm new file mode 100644 index 000000000..5fe9dcf09 --- /dev/null +++ b/src/cloud/outscale/mode/listinternetservices.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listinternetservices; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'internet-service-tag-name:s' => { name => 'internet_service_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_internet_service_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{internet_service_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $services = $options{custom}->read_internet_services(); + + my $results = {}; + foreach (@$services) { + my $name = $self->get_internet_service_name(tags => $_->{Tags}, id => $_->{InternetServiceId}); + + $results->{ $_->{InternetServiceId} } = { + id => $_->{InternetServiceId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List internet services:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List internet services. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listloadbalancers.pm b/src/cloud/outscale/mode/listloadbalancers.pm new file mode 100644 index 000000000..078952452 --- /dev/null +++ b/src/cloud/outscale/mode/listloadbalancers.pm @@ -0,0 +1,107 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listloadbalancers; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('name', 'type'); + +sub manage_selection { + my ($self, %options) = @_; + + my $lbs = $options{custom}->load_balancer_read(); + + my $results = {}; + foreach (@$lbs) { + $results->{ $_->{LoadBalancerName} } = { + name => $_->{LoadBalancerName}, + type => $_->{LoadBalancerType} + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List load balancers:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List load balancers. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listnatservices.pm b/src/cloud/outscale/mode/listnatservices.pm new file mode 100644 index 000000000..52aa275d6 --- /dev/null +++ b/src/cloud/outscale/mode/listnatservices.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listnatservices; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'nat-tag-name:s' => { name => 'nat_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_nat_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{nat_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $services = $options{custom}->read_nat_services(); + + my $results = {}; + foreach (@$services) { + my $name = $self->get_nat_name(tags => $_->{Tags}, id => $_->{NatServiceId}); + + $results->{ $_->{NatServiceId} } = { + id => $_->{NatServiceId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List nat services:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List nat services. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listnets.pm b/src/cloud/outscale/mode/listnets.pm new file mode 100644 index 000000000..771faa2a9 --- /dev/null +++ b/src/cloud/outscale/mode/listnets.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listnets; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'net-tag-name:s' => { name => 'net_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_net_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{net_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $nets = $options{custom}->read_nets(); + + my $results = {}; + foreach (@$nets) { + my $name = $self->get_net_name(tags => $_->{Tags}, id => $_->{NetId}); + + $results->{$name} = { + id => $_->{NetId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List nets:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List nets. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listquotas.pm b/src/cloud/outscale/mode/listquotas.pm new file mode 100644 index 000000000..77f5d4338 --- /dev/null +++ b/src/cloud/outscale/mode/listquotas.pm @@ -0,0 +1,107 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listquotas; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('name', 'type'); + +sub manage_selection { + my ($self, %options) = @_; + + my $quotas = $options{custom}->read_quotas(); + + my $results = []; + foreach my $quota (@$quotas) { + foreach (@{$quota->{Quotas}}) { + push @$results, { + name => $_->{Name}, + type => $quota->{QuotaType} + }; + } + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $entry (@$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $entry->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List quotas:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $entry (@$results) { + $self->{output}->add_disco_entry(%$entry); + } +} +1; + +__END__ + +=head1 MODE + +List quotas. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listroutetables.pm b/src/cloud/outscale/mode/listroutetables.pm new file mode 100644 index 000000000..155513d80 --- /dev/null +++ b/src/cloud/outscale/mode/listroutetables.pm @@ -0,0 +1,106 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listroutetables; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id'); + +sub manage_selection { + my ($self, %options) = @_; + + my $tables = $options{custom}->read_route_tables(); + + my $results = {}; + foreach (@$tables) { + $results->{ $_->{RouteTableId} } = { + id => $_->{RouteTableId} + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List route tables:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List route tables. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listsubnets.pm b/src/cloud/outscale/mode/listsubnets.pm new file mode 100644 index 000000000..433a576e3 --- /dev/null +++ b/src/cloud/outscale/mode/listsubnets.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listsubnets; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'subnet-tag-name:s' => { name => 'subnet_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_subnet_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{subnet_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $subnets = $options{custom}->read_subnets(); + + my $results = {}; + foreach (@$subnets) { + my $name = $self->get_subnet_name(tags => $_->{Tags}, id => $_->{SubnetId}); + + $results->{$name} = { + id => $_->{SubnetId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List subnets:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List subnets. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listvirtualgateways.pm b/src/cloud/outscale/mode/listvirtualgateways.pm new file mode 100644 index 000000000..2230c1563 --- /dev/null +++ b/src/cloud/outscale/mode/listvirtualgateways.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listvirtualgateways; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'vg-tag-name:s' => { name => 'vg_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_vg_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vg_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $vgs = $options{custom}->read_virtual_gateways(); + + my $results = {}; + foreach (@$vgs) { + my $name = $self->get_vg_name(tags => $_->{Tags}, id => $_->{VirtualGatewayId}); + + $results->{$name} = { + id => $_->{VirtualGatewayId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List virtual gateways:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List virtual gateways. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listvms.pm b/src/cloud/outscale/mode/listvms.pm new file mode 100644 index 000000000..6888c61fb --- /dev/null +++ b/src/cloud/outscale/mode/listvms.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listvms; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'vm-tag-name:s' => { name => 'vm_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_vm_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vm_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $vms = $options{custom}->read_vms(); + + my $results = {}; + foreach (@$vms) { + my $name = $self->get_vm_name(tags => $_->{Tags}, id => $_->{VmId}); + + $results->{ $_->{VmId} } = { + id => $_->{VmId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List virtual machines:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List virtual machines. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listvolumes.pm b/src/cloud/outscale/mode/listvolumes.pm new file mode 100644 index 000000000..68fb7fd76 --- /dev/null +++ b/src/cloud/outscale/mode/listvolumes.pm @@ -0,0 +1,109 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listvolumes; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'region', 'type', 'state'); + +sub manage_selection { + my ($self, %options) = @_; + + my $volumes = $options{custom}->read_volumes(); + + my $results = {}; + foreach (@$volumes) { + $results->{ $_->{VolumeId} } = { + id => $_->{VolumeId}, + region => $_->{SubregionName}, + type => $_->{VolumeType}, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List volumes:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List volumes. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/listvpnconnections.pm b/src/cloud/outscale/mode/listvpnconnections.pm new file mode 100644 index 000000000..3e2b51ab2 --- /dev/null +++ b/src/cloud/outscale/mode/listvpnconnections.pm @@ -0,0 +1,122 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::listvpnconnections; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'vpn-tag-name:s' => { name => 'vpn_tag_name', default => 'name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my @labels = ('id', 'name', 'state'); + +sub get_vpn_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vpn_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $connections = $options{custom}->read_vpn_connections(); + + my $results = {}; + foreach (@$connections) { + my $name = $self->get_vpn_name(tags => $_->{Tags}, id => $_->{VpnConnectionId}); + + $results->{$name} = { + id => $_->{VpnConnectionId}, + name => $name, + state => lc($_->{State}) + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels)) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List vpn connections:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => [@labels]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(custom => $options{custom}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} +1; + +__END__ + +=head1 MODE + +List vpn connections. + +=over 8 + +=back + +=cut diff --git a/src/cloud/outscale/mode/loadbalancers.pm b/src/cloud/outscale/mode/loadbalancers.pm new file mode 100644 index 000000000..2db9d662d --- /dev/null +++ b/src/cloud/outscale/mode/loadbalancers.pm @@ -0,0 +1,225 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::loadbalancers; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub lb_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking load balancer '%s'", + $options{instance_value}->{name} + ); +} + +sub prefix_lb_output { + my ($self, %options) = @_; + + return sprintf( + "load balancer '%s' ", + $options{instance_value}->{name} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Number of load balancers '; +} + +sub prefix_vm_metrics_output { + my ($self, %options) = @_; + + return 'number of virtual machines '; +} + +sub prefix_vm_output { + my ($self, %options) = @_; + + return "virtual machine '" . $options{instance_value}->{vmName} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { + name => 'lbs', type => 3, cb_prefix_output => 'prefix_lb_output', cb_long_output => 'lb_long_output', indent_long_output => ' ', message_multiple => 'All load balancers are ok', + group => [ + { name => 'vm_metrics', type => 0, cb_prefix_output => 'prefix_vm_metrics_output' }, + { name => 'vms', display_long => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'all virtual machines are ok', type => 1, skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'load-balancers-detected', display_ok => 0, nlabel => 'load_balancers.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{vm_metrics} = [ + { label => 'load-balancer-vms-up', nlabel => 'load_balancer.virtual_machines.up.count', set => { + key_values => [ { name => 'up' } ], + output_template => 'up: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'load-balancer-vms-down', nlabel => 'load_balancer.virtual_machines.down.count', set => { + key_values => [ { name => 'down' } ], + output_template => 'down: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; + + $self->{maps_counters}->{vms} = [ + { + label => 'vm-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'vmName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'vm-tag-name:s' => { name => 'vm_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_vm_name { + my ($self, %options) = @_; + + foreach my $vm (@{$options{vms}}) { + next if ($vm->{VmId} ne $options{vm_id}); + + foreach my $tag (@{$vm->{Tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vm_tag_name}$/i); + } + } + + return $options{vm_id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $lbs = $options{custom}->load_balancer_read(); + my $vms = $options{custom}->read_vms(); + + $self->{global} = { detected => 0 }; + $self->{lbs} = {}; + + foreach my $lb (@$lbs) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $lb->{LoadBalancerName} !~ /$self->{option_results}->{filter_name}/); + + $self->{global}->{detected}++; + + $self->{lbs}->{ $lb->{LoadBalancerName} } = { + name => $lb->{LoadBalancerName}, + vm_metrics => { up => 0, down => 0 }, + vms => {} + }; + + my $members = $options{custom}->read_vms_health(load_balancer_name => $lb->{LoadBalancerName}); + foreach (@$members) { + my $name = $self->get_vm_name(vms => $vms, vm_id => $_->{VmId}); + + $self->{lbs}->{ $lb->{LoadBalancerName} }->{vms}->{ $_->{VmId} } = { + vmName => $name, + state => lc($_->{State}) + }; + $self->{lbs}->{ $lb->{LoadBalancerName} }->{vm_metrics}->{ lc($_->{State}) }++ + if (defined($self->{lbs}->{ $lb->{LoadBalancerName} }->{vm_metrics}->{ lc($_->{State}) })); + } + } +} + +1; + +__END__ + +=head1 MODE + +Check load balancers. + +=over 8 + +=item B<--filter-name> + +Filter load balancers by name. + +=item B<--vm-tag-name> + +Virtual machine tags to used for the name (Default: 'name'). + +=item B<--unknown-vm-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{vmName} + +=item B<--warning-vm-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{vmName} + +=item B<--critical-vm-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{vmName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'load-balancers-detected', 'load-balancer-vms-up', ''load-balancer-vms-down'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/natservices.pm b/src/cloud/outscale/mode/natservices.pm new file mode 100644 index 000000000..e8b6a8ffe --- /dev/null +++ b/src/cloud/outscale/mode/natservices.pm @@ -0,0 +1,175 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::natservices; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_service_output { + my ($self, %options) = @_; + + return sprintf( + "nat service '%s' ", + $options{instance_value}->{natName} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of nat services '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'services', type => 1, cb_prefix_output => 'prefix_service_output', message_multiple => 'All nat services are ok' } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('detected', 'pending', 'available', 'deleting', 'deleted') { + push @{$self->{maps_counters}->{global}}, { + label => 'nat-services-' . $_, display_ok => 0, nlabel => 'nat_services.' . $_ . '.count', set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{services} = [ + { + label => 'nat-service-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'natName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-id:s' => { name => 'filter_id' }, + 'filter-name:s' => { name => 'filter_name' }, + 'nat-tag-name:s' => { name => 'nat_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_nat_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{nat_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $services = $options{custom}->read_nat_services(); + + $self->{global} = { detected => 0, pending => 0, available => 0, deleting => 0, deleted => 0 }; + $self->{services} = {}; + + foreach (@$services) { + my $name = $self->get_nat_name(tags => $_->{Tags}, id => $_->{NatServiceId}); + + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $_->{NatServiceId} !~ /$self->{option_results}->{filter_id}/); + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{services}->{ $_->{NatServiceId} } = { + natName => $name, + state => lc($_->{State}) + }; + + $self->{global}->{ lc($_->{State}) }++ + if (defined($self->{global}->{ lc($_->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check nat services. + +=over 8 + +=item B<--filter-id> + +Filter nat services by id. + +=item B<--filter-name> + +Filter nat services by name. + +=item B<--nat-tag-name> + +Nat service tag to be used for the name (Default: 'name'). + +=item B<--unknown-nat-service-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{natName} + +=item B<--warning-nat-service-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{natName} + +=item B<--critical-nat-service-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{natName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'nat-services-detected', 'nat-services-pending', 'nat-services-available', +'nat-services-deleting', 'nat-services-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/nets.pm b/src/cloud/outscale/mode/nets.pm new file mode 100644 index 000000000..ec15197d2 --- /dev/null +++ b/src/cloud/outscale/mode/nets.pm @@ -0,0 +1,168 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::nets; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_net_output { + my ($self, %options) = @_; + + return sprintf( + "net '%s' ", + $options{instance_value}->{netName} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of nets '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'nets', type => 1, cb_prefix_output => 'prefix_net_output', message_multiple => 'All nets are ok' } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('detected', 'pending', 'available', 'deleted') { + push @{$self->{maps_counters}->{global}}, { + label => 'nets-' . $_, display_ok => 0, nlabel => 'nets.' . $_ . '.count', set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{nets} = [ + { + label => 'net-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'netName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'net-tag-name:s' => { name => 'net_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_net_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{net_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $nets = $options{custom}->read_nets(); + + $self->{global} = { detected => 0, available => 0, pending => 0, deleted => 0 }; + $self->{nets} = {}; + + foreach my $net (@$nets) { + my $name = $self->get_net_name(tags => $net->{Tags}, id => $net->{NetId}); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{nets}->{$name} = { + netName => $name, + state => lc($net->{State}) + }; + + $self->{global}->{ lc($net->{State}) }++ + if (defined($self->{global}->{ lc($net->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check nets. + +=over 8 + +=item B<--filter-name> + +Filter nets by name. + +=item B<--net-tag-name> + +Nets tag to be used for the name (Default: 'name'). + +=item B<--unknown-net-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{netName} + +=item B<--warning-net-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{netName} + +=item B<--critical-net-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{netName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'nets-detected', 'nets-available', 'nets-pending', +'nets-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/quotas.pm b/src/cloud/outscale/mode/quotas.pm new file mode 100644 index 000000000..268c01151 --- /dev/null +++ b/src/cloud/outscale/mode/quotas.pm @@ -0,0 +1,200 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::quotas; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_quota_output { + my ($self, %options) = @_; + + return sprintf( + 'total: %s used: %s (%.2f%%) free: %s (%.2f%%)', + $self->{result_values}->{total}, + $self->{result_values}->{used}, + $self->{result_values}->{prct_used}, + $self->{result_values}->{free}, + $self->{result_values}->{prct_free} + ); +} + +sub prefix_quota_output { + my ($self, %options) = @_; + + return sprintf( + "quota '%s' [type: %s] ", + $options{instance_value}->{name}, + $options{instance_value}->{type} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'quotas', type => 1, cb_prefix_output => 'prefix_quota_output', message_multiple => 'All quotas are ok' } + ]; + + $self->{maps_counters}->{quotas} = [ + { label => 'quota-usage', nlabel => 'quota.usage.count', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' }, { name => 'type' } ], + closure_custom_output => $self->can('custom_quota_output'), + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => [$self->{result_values}->{type}, $self->{result_values}->{name}], + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => $self->{result_values}->{total} + ); + } + } + }, + { label => 'quota-usage-free', display_ok => 0, nlabel => 'quota.free.count', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' }, { name => 'type' } ], + closure_custom_output => $self->can('custom_quota_output'), + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => [$self->{result_values}->{type}, $self->{result_values}->{name}], + value => $self->{result_values}->{free}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => $self->{result_values}->{total} + ); + } + } + }, + { label => 'quota-usage-prct', display_ok => 0, nlabel => 'quota.usage.percentage', set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' }, { name => 'type' } ], + closure_custom_output => $self->can('custom_quota_output'), + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => '%', + instances => [$self->{result_values}->{type}, $self->{result_values}->{name}], + value => sprintf('%.2f', $self->{result_values}->{prct_used}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => 100 + ); + } + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'filter-type:s' => { name => 'filter_type' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $quotas = $options{custom}->read_quotas(); + + my $i = 0; + $self->{quotas} = {}; + foreach my $quota (@$quotas) { + next if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $quota->{QuotaType} !~ /$self->{option_results}->{filter_type}/); + foreach (@{$quota->{Quotas}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $_->{Name} !~ /$self->{option_results}->{filter_name}/); + next if ($_->{MaxValue} <= 0); + + $self->{quotas}->{$i} = { + name => $_->{Name}, + type => $quota->{QuotaType}, + total => $_->{MaxValue}, + used => $_->{UsedValue}, + free => $_->{MaxValue} - $_->{UsedValue}, + prct_used => $_->{UsedValue} * 100 / $_->{MaxValue}, + prct_free => 100 - ($_->{UsedValue} * 100 / $_->{MaxValue}) + }; + $i++; + } + } +} + +1; + +__END__ + +=head1 MODE + +Check quotas. + +=over 8 + +=item B<--filter-name> + +Filter nets by name. + +=item B<--net-tag-name> + +Nets tag to be used for the name (Default: 'name'). + +=item B<--unknown-net-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{netName} + +=item B<--warning-net-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{netName} + +=item B<--critical-net-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{netName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'nets-detected', 'nets-available', 'nets-pending', +'nets-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/routetables.pm b/src/cloud/outscale/mode/routetables.pm new file mode 100644 index 000000000..4344ffe80 --- /dev/null +++ b/src/cloud/outscale/mode/routetables.pm @@ -0,0 +1,127 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::routetables; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_table_output { + my ($self, %options) = @_; + + return sprintf( + "route table '%s' ", + $options{instance} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of route tables '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'tables', type => 1, cb_prefix_output => 'prefix_table_output', message_multiple => 'All route tables are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'route-tables-detected', display_ok => 0, nlabel => 'route_tables.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{tables} = [ + { label => 'route-tables-routes', nlabel => 'route_tables.routes.count', set => { + key_values => [ { name => 'num_routes' } ], + output_template => 'number of routes: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-route-table-id:s' => { name => 'filter_route_table_id' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $tables = $options{custom}->read_route_tables(); + + $self->{global} = { detected => 0 }; + $self->{tables} = {}; + + foreach (@$tables) { + next if (defined($self->{option_results}->{filter_route_table_id}) && $self->{option_results}->{filter_route_table_id} ne '' && + $_->{RouteTableId} !~ /$self->{option_results}->{filter_route_table_id}/); + + $self->{tables}->{ $_->{RouteTableId} } = { + num_routes => scalar(@{$_->{Routes}}), + }; + + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check route tables. + +=over 8 + +=item B<--filter-route-table-id> + +Filter route tables by id. + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'route-tables-detected', 'route-tables-routes'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/subnets.pm b/src/cloud/outscale/mode/subnets.pm new file mode 100644 index 000000000..b840b9c01 --- /dev/null +++ b/src/cloud/outscale/mode/subnets.pm @@ -0,0 +1,213 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::subnets; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_subnet_output { + my ($self, %options) = @_; + + return sprintf( + 'total: %s used: %s (%.2f%%) free: %s (%.2f%%)', + $self->{result_values}->{total}, + $self->{result_values}->{used}, + $self->{result_values}->{prct_used}, + $self->{result_values}->{free}, + $self->{result_values}->{prct_free} + ); +} + +sub subnet_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking subnet '%s'", + $options{instance_value}->{name} + ); +} + +sub prefix_subnet_output { + my ($self, %options) = @_; + + return sprintf( + "subnet '%s' ", + $options{instance_value}->{name} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of subnets '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { + name => 'subnets', type => 3, cb_prefix_output => 'prefix_subnet_output', cb_long_output => 'subnet_long_output', indent_long_output => ' ', message_multiple => 'All subnets are ok', + group => [ + { name => 'status', type => 0 }, + { name => 'metrics', type => 0 } + ] + } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('detected', 'pending', 'available', 'deleted') { + push @{$self->{maps_counters}->{global}}, { + label => 'subnets-' . $_, display_ok => 0, nlabel => 'subnets.' . $_ . '.count', set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{status} = [ + { + label => 'subnet-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'subnetName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{metrics} = [ + { label => 'subnet-addresses-usage-free', nlabel => 'subnet.addresses.free.count', set => { + key_values => [ { name => 'freeAddresses' }, { name => 'subnetName'} ], + output_template => 'number of addresses free: %s', + perfdatas => [ + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'subnetName' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'subnet-tag-name:s' => { name => 'subnet_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_subnet_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{subnet_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $subnets = $options{custom}->read_subnets(); + + $self->{global} = { available => 0, pending => 0, deleted => 0 }; + $self->{subnets} = {}; + foreach (@$subnets) { + my $name = $self->get_subnet_name(tags => $_->{Tags}, id => $_->{SubnetId}); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{subnets}->{ $_->{SubnetId} } = { + name => $name, + status => { + subnetName => $name, + state => lc($_->{State}) + }, + metrics => { + subnetName => $name, + freeAddresses => $_->{AvailableIpsCount} + } + }; + + $self->{global}->{ lc($_->{State}) }++ + if (defined($self->{global}->{ lc($_->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check subnets. + +=over 8 + +=item B<--filter-name> + +Filter subnets by name. + +=item B<--subnet-tag-name> + +Subnet tags to be used for the name (Default: 'name'). + +=item B<--unknown-subnet-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{subnetName} + +=item B<--warning-subnet-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{subnetName} + +=item B<--critical-subnet-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{subnetName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'subnets-detected', 'subnets-available', 'subnets-pending', +'subnets-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/virtualgateways.pm b/src/cloud/outscale/mode/virtualgateways.pm new file mode 100644 index 000000000..bc3c4ad0b --- /dev/null +++ b/src/cloud/outscale/mode/virtualgateways.pm @@ -0,0 +1,198 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::virtualgateways; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_vg_output { + my ($self, %options) = @_; + + return sprintf( + "virtual gateway '%s' ", + $options{instance_value}->{vgName} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of virtual gateways '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'vgs', type => 1, cb_prefix_output => 'prefix_vg_output', message_multiple => 'All virtual gateways are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'vgs-detected', display_ok => 0, nlabel => 'virtual_gateways.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vgs-available', display_ok => 0, nlabel => 'virtual_gateways.available.count', set => { + key_values => [ { name => 'available' } ], + output_template => 'available: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vgs-pending', display_ok => 0, nlabel => 'virtual_gateways.pending.count', set => { + key_values => [ { name => 'pending' } ], + output_template => 'pending: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vgs-deleting', display_ok => 0, nlabel => 'virtual_gateways.deleting.count', set => { + key_values => [ { name => 'deleting' } ], + output_template => 'deleting: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vgs-deleted', display_ok => 0, nlabel => 'virtual_gateways.deleted.count', set => { + key_values => [ { name => 'deleted' } ], + output_template => 'deleted: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{vgs} = [ + { + label => 'vg-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'vgName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'vg-tag-name:s' => { name => 'vg_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_vg_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vg_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $vgs = $options{custom}->read_virtual_gateways(); + + $self->{global} = { detected => 0, available => 0, pending => 0, deleting => 0, deleted => 0 }; + $self->{vgs} = {}; + + foreach my $vg (@$vgs) { + my $name = $self->get_vg_name(tags => $vg->{Tags}, id => $vg->{VirtualGatewayId}); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{vgs}->{$name} = { + vgName => $name, + state => lc($vg->{State}) + }; + + $self->{global}->{ lc($vg->{State}) }++ + if (defined($self->{global}->{ lc($vg->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check virtual gateways. + +=over 8 + +=item B<--filter-name> + +Filter virtual gateways by name. + +=item B<--vg-tag-name> + +Virtual gateway tag to be used for the name (Default: 'name'). + +=item B<--unknown-vg-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{vgName} + +=item B<--warning-vg-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{vgName} + +=item B<--critical-vg-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{vgName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'vgs-detected', 'vgs-available', 'vgs-pending', +'vgs-deleting', 'vgs-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/vms.pm b/src/cloud/outscale/mode/vms.pm new file mode 100644 index 000000000..cfe8060ca --- /dev/null +++ b/src/cloud/outscale/mode/vms.pm @@ -0,0 +1,175 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::vms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_vm_output { + my ($self, %options) = @_; + + return sprintf( + "virtual machine '%s' ", + $options{instance_value}->{vmName} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of virtual machines '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'vms', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('detected', 'pending', 'running', 'stopping', 'stopped', 'shutting-down', 'terminated', 'quarantine') { + push @{$self->{maps_counters}->{global}}, { + label => 'vms-' . $_, display_ok => 0, nlabel => 'virtual_machines.' . $_ . '.count', set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{vms} = [ + { + label => 'vm-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'vmName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-id:s' => { name => 'filter_id' }, + 'filter-name:s' => { name => 'filter_name' }, + 'vm-tag-name:s' => { name => 'vm_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_vm_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vm_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $vms = $options{custom}->read_vms(); + + $self->{global} = { detected => 0, pending => 0, running => 0, stopping => 0, stopped => 0, 'shutting-down' => 0, terminated => 0, quarantine => 0 }; + $self->{vms} = {}; + + foreach (@$vms) { + my $name = $self->get_vm_name(tags => $_->{Tags}, id => $_->{VmId}); + + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $_->{VmId} !~ /$self->{option_results}->{filter_id}/); + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{vms}->{ $_->{VmId} } = { + vmName => $name, + state => lc($_->{State}) + }; + + $self->{global}->{ lc($_->{State}) }++ + if (defined($self->{global}->{ lc($_->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check virtual machines. + +=over 8 + +=item B<--filter-id> + +Filter virtual machines by id. + +=item B<--filter-name> + +Filter virtual machines by name. + +=item B<--vm-tag-name> + +Virtual machine tag to be used for the name (Default: 'name'). + +=item B<--unknown-vm-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{vmName} + +=item B<--warning-vm-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{vmName} + +=item B<--critical-vm-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{vmName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'vms-detected', 'vms-pending', 'vms-running', 'vms-stopping', +'vms-stopped', 'vms-shutting-down', 'vms-terminated', 'vms-quarantine'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/volumes.pm b/src/cloud/outscale/mode/volumes.pm new file mode 100644 index 000000000..b32e86e54 --- /dev/null +++ b/src/cloud/outscale/mode/volumes.pm @@ -0,0 +1,218 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::volumes; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub volume_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking volume '%s'", + $options{instance_value}->{id} + ); +} + +sub prefix_volume_output { + my ($self, %options) = @_; + + return sprintf( + "volume '%s' ", + $options{instance_value}->{id} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of volumes '; +} + +sub prefix_vm_output { + my ($self, %options) = @_; + + return "virtual machine '" . $options{instance_value}->{vmName} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { + name => 'volumes', type => 3, cb_prefix_output => 'prefix_volume_output', cb_long_output => 'volume_long_output', indent_long_output => ' ', message_multiple => 'All volumes are ok', + group => [ + { name => 'status', type => 0 }, + { name => 'vms', display_long => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'all virtual machines are ok', type => 1, skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('detected', 'creating', 'available', 'in-use', 'updating', 'deleting', 'error') { + push @{$self->{maps_counters}->{global}}, { + label => 'volumes-' . $_, display_ok => 0, nlabel => 'volumes.' . $_ . '.count', set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{status} = [ + { + label => 'volume-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'volumeId' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{vms} = [ + { + label => 'vm-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'vmName' } ], + output_template => 'volume state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-id:s' => { name => 'filter_id' }, + 'vm-tag-name:s' => { name => 'vm_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_vm_name { + my ($self, %options) = @_; + + foreach my $vm (@{$options{vms}}) { + next if ($vm->{VmId} ne $options{vm_id}); + + foreach my $tag (@{$vm->{Tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vm_tag_name}$/i); + } + } + + return $options{vm_id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $volumes = $options{custom}->read_volumes(); + my $vms = $options{custom}->read_vms(); + + $self->{global} = { detected => 0, creating => 0, available => 0, 'in-use' => 0, updating => 0, deleting => 0, error => 0 }; + $self->{volumes} = {}; + + foreach my $volume (@$volumes) { + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $volume->{VolumeId} !~ /$self->{option_results}->{filter_id}/); + + $self->{volumes}->{ $volume->{VolumeId} } = { + id => $volume->{VolumeId}, + status => { + volumeId => $volume->{VolumeId}, + state => lc($volume->{State}) + }, + vms => {} + }; + + $self->{global}->{ lc($volume->{State}) }++ + if (defined($self->{global}->{ lc($volume->{State}) })); + $self->{global}->{detected}++; + + foreach (@{$volume->{LinkedVolumes}}) { + my $name = $self->get_vm_name(vms => $vms, vm_id => $_->{VmId}); + + $self->{volumes}->{ $volume->{VolumeId} }->{vms}->{ $_->{VmId} } = { + vmName => $name, + state => lc($_->{State}) + }; + } + } +} + +1; + +__END__ + +=head1 MODE + +Check volumes. + +=over 8 + +=item B<--filter-id> + +Filter volumes by id. + +=item B<--vm-tag-name> + +Virtual machine tags to used for the name (Default: 'name'). + +=item B<--unknown-volume-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{volumeId} + +=item B<--warning-volume-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{volumeId} + +=item B<--critical-volume-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{volumeId} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'volumes-detected', 'volumes-creating', 'volumes-available', +'volumes-in-use', 'volumes-updating', 'volumes-deleting', 'volumes-error'. + +=back + +=cut diff --git a/src/cloud/outscale/mode/vpnconnections.pm b/src/cloud/outscale/mode/vpnconnections.pm new file mode 100644 index 000000000..a2d822dc7 --- /dev/null +++ b/src/cloud/outscale/mode/vpnconnections.pm @@ -0,0 +1,215 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::mode::vpnconnections; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub vpn_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking vpn connection '%s'", + $options{instance_value}->{name} + ); +} + +sub prefix_vpn_output { + my ($self, %options) = @_; + + return sprintf( + "vpn connection '%s' ", + $options{instance_value}->{name} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of vpn connections '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { + name => 'connections', type => 3, cb_prefix_output => 'prefix_vpn_output', cb_long_output => 'vpn_long_output', indent_long_output => ' ', message_multiple => 'All vpn connections are ok', + group => [ + { name => 'status', type => 0 } + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'vpn-connections-detected', display_ok => 0, nlabel => 'vpn_connections.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vpn-connections-available', display_ok => 0, nlabel => 'vpn_connections.available.count', set => { + key_values => [ { name => 'available' } ], + output_template => 'available: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vpn-connections-pending', display_ok => 0, nlabel => 'vpn_connections.pending.count', set => { + key_values => [ { name => 'pending' } ], + output_template => 'pending: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vpn-connections-deleting', display_ok => 0, nlabel => 'vpn_connections.deleting.count', set => { + key_values => [ { name => 'deleting' } ], + output_template => 'deleting: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'vpn-connections-deleted', display_ok => 0, nlabel => 'vpn_connections.deleted.count', set => { + key_values => [ { name => 'deleted' } ], + output_template => 'deleted: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{status} = [ + { + label => 'vpn-connection-status', + type => 2, + set => { + key_values => [ { name => 'state' }, { name => 'vpnName' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'vpn-tag-name:s' => { name => 'vpn_tag_name', default => 'name' } + }); + + return $self; +} + +sub get_vpn_name { + my ($self, %options) = @_; + + foreach my $tag (@{$options{tags}}) { + return $tag->{Value} if ($tag->{Key} =~ /^$self->{option_results}->{vpn_tag_name}$/i); + } + + return $options{id}; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $connections = $options{custom}->read_vpn_connections(); + + $self->{global} = { detected => 0, available => 0, pending => 0, deleting => 0, deleted => 0 }; + $self->{connections} = {}; + + foreach my $connection (@$connections) { + my $name = $self->get_vpn_name(tags => $connection->{Tags}, id => $connection->{VpnConnectionId}); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/); + + $self->{connections}->{$name} = { + name => $name, + status => { + vpnName => $name, + state => lc($connection->{State}) + } + }; + + $self->{global}->{ lc($connection->{State}) }++ + if (defined($self->{global}->{ lc($connection->{State}) })); + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check vpn connections. + +=over 8 + +=item B<--filter-name> + +Filter virtual connections by name. + +=item B<--vpn-tag-name> + +Vpn connection tag to be used for the name (Default: 'name'). + +=item B<--unknown-vpn-connection-status> + +Set unknown threshold for status. +Can used special variables like: %{state}, %{vpnName} + +=item B<--warning-vpn-connection-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{vpnName} + +=item B<--critical-vpn-connection-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{vpnName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'vpn-connections-detected', 'vpn-connections-available', 'vpn-connections-pending', +'vpn-connections-deleting', 'vpn-connections-deleted'. + +=back + +=cut diff --git a/src/cloud/outscale/plugin.pm b/src/cloud/outscale/plugin.pm new file mode 100644 index 000000000..879164dc2 --- /dev/null +++ b/src/cloud/outscale/plugin.pm @@ -0,0 +1,73 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::outscale::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'account-consumptions' => 'cloud::outscale::mode::accountconsumptions', + 'client-gateways' => 'cloud::outscale::mode::clientgateways', + 'internet-services' => 'cloud::outscale::mode::internetservices', + 'list-client-gateways' => 'cloud::outscale::mode::listclientgateways', + 'list-internet-services' => 'cloud::outscale::mode::listinternetservices', + 'list-load-balancers' => 'cloud::outscale::mode::listloadbalancers', + 'list-nat-services' => 'cloud::outscale::mode::listnatservices', + 'list-nets' => 'cloud::outscale::mode::listnets', + 'list-quotas' => 'cloud::outscale::mode::listquotas', + 'list-route-tables' => 'cloud::outscale::mode::listroutetables', + 'list-subnets' => 'cloud::outscale::mode::listsubnets', + 'list-virtual-gateways' => 'cloud::outscale::mode::listvirtualgateways', + 'list-volumes' => 'cloud::outscale::mode::listvolumes', + 'list-vms' => 'cloud::outscale::mode::listvms', + 'list-vpn-connections' => 'cloud::outscale::mode::listvpnconnections', + 'load-balancers' => 'cloud::outscale::mode::loadbalancers', + 'nat-services' => 'cloud::outscale::mode::natservices', + 'nets' => 'cloud::outscale::mode::nets', + 'quotas' => 'cloud::outscale::mode::quotas', + 'route-tables' => 'cloud::outscale::mode::routetables', + 'subnets' => 'cloud::outscale::mode::subnets', + 'virtual-gateways' => 'cloud::outscale::mode::virtualgateways', + 'volumes' => 'cloud::outscale::mode::volumes', + 'vms' => 'cloud::outscale::mode::vms', + 'vpn-connections' => 'cloud::outscale::mode::vpnconnections' + }; + + $self->{custom_modes}->{http} = 'cloud::outscale::custom::http'; + $self->{custom_modes}->{osccli} = 'cloud::outscale::custom::osccli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Outscale. + +=cut From 659e49d2d8a676feaf62859dd8a7cc2d3a3a2547 Mon Sep 17 00:00:00 2001 From: YanMeddour <83709929+YanMeddour@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:52:20 +0200 Subject: [PATCH 388/447] (plugin) apps::java::jvm::actuator - manage new centreon-map new auth endpoint --- .../protocols/actuator/custom/centreonmap.pm | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/centreon/common/protocols/actuator/custom/centreonmap.pm b/src/centreon/common/protocols/actuator/custom/centreonmap.pm index 7352b56a8..b396a369d 100644 --- a/src/centreon/common/protocols/actuator/custom/centreonmap.pm +++ b/src/centreon/common/protocols/actuator/custom/centreonmap.pm @@ -158,59 +158,70 @@ sub clean_session { my $datas = {}; $options{statefile}->write(data => $datas); - $self->{studio_session} = undef; } sub get_session { my ($self, %options) = @_; - my $has_cache_file = $options{statefile}->read(statefile => 'centreonmap_session_' . md5_hex($self->{option_results}->{hostname}) . '_' . md5_hex($self->{option_results}->{api_username})); - my $studio_session = $options{statefile}->get(name => 'studio_session'); + my $has_cache_file = $options{statefile}->read(statefile => 'centreonmap_session_' . md5_hex($self->{option_results}->{hostname}) . '_' . md5_hex($self->{api_username})); + my $studio_session = $options{statefile}->get(name => 'studioSession'); + my $jwt_token = $options{statefile}->get(name => 'jwtToken'); + my $md5_secret_cache = $self->{cache}->get(name => 'md5_secret'); + my $md5_secret = md5_hex($self->{api_username} . $self->{api_password}); - if ($has_cache_file == 0 || !defined($studio_session)) { + if ($has_cache_file == 0 || + (!defined($studio_session) && !defined($jwt_token)) || + (defined($md5_secret_cache) && $md5_secret_cache ne $md5_secret) + ) { my $login = { login => $self->{api_username}, password => $self->{api_password} }; my $post_json = JSON::XS->new->utf8->encode($login); - my ($content) = $self->{http}->request( - method => 'POST', - url_path => $self->{url_path} . '/authentication', - header => ['Content-type: application/json'], - query_form_post => $post_json, - warning_status => '', unknown_status => '', critical_status => '' - ); + my @urls = ('/auth/sign-in', '/authentication'); + my $content; + for my $endpoint (@urls) { + ($content) = $self->{http}->request( + method => 'POST', + url_path => $self->{url_path} . $endpoint, + header => ['Content-type: application/json'], + query_form_post => $post_json, + warning_status => '', unknown_status => '', critical_status => '' + ); + last if ($self->{http}->get_code() == 200); + } if ($self->{http}->get_code() != 200) { - $self->{output}->add_option_msg(short_msg => "Authentication error [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->add_option_msg(short_msg => "All authentication URLs failed"); $self->{output}->option_exit(); } my $decoded = $self->json_decode(content => $content); - if (!defined($decoded->{studioSession})) { - $self->{output}->add_option_msg(short_msg => 'Cannot studio session'); + if (!defined($decoded->{studioSession}) && !defined($decoded->{jwtToken})) { + $self->{output}->add_option_msg(short_msg => 'Cannot get session token'); $self->{output}->option_exit(); } - $studio_session = $decoded->{studioSession}; - $options{statefile}->write(data => { studio_session => $studio_session }); + if (defined($decoded->{studioSession})) { + $studio_session = $decoded->{studioSession}; + $options{statefile}->write(data => { studio_session => $studio_session, md5_secret => $md5_secret }); + } else { + $jwt_token = $decoded->{jwtToken}; + $options{statefile}->write(data => { jwtToken => $jwt_token, md5_secret => $md5_secret }); + } } - $self->{studio_session} = $studio_session; + return defined($studio_session) ? 'studio-session: ' . $studio_session : 'Authorization: Bearer ' . $jwt_token; } sub request_api { my ($self, %options) = @_; $self->settings(); - if (!defined($self->{studio_session})) { - $self->get_session(statefile => $self->{cache}); - } + my $header = $self->get_session(statefile => $self->{cache}); my $content = $self->{http}->request( url_path => $self->{url_path} . '/actuator' . $options{endpoint}, get_param => $options{get_param}, - header => [ - 'studio-session: ' . $self->{studio_session} - ], + header => [ $header ], warning_status => '', unknown_status => '', critical_status => '' @@ -219,13 +230,12 @@ sub request_api { # Maybe there is an issue with the token. So we retry. if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { $self->clean_session(statefile => $self->{cache}); - $self->get_session(statefile => $self->{cache}); + $header = $self->get_session(statefile => $self->{cache}); + $content = $self->{http}->request( url_path => $self->{url_path} . '/actuator' . $options{endpoint}, get_param => $options{get_param}, - header => [ - 'studio-session: ' . $self->{studio_session} - ], + header => [ $header ], unknown_status => $self->{unknown_http_status}, warning_status => $self->{warning_http_status}, critical_status => $self->{critical_http_status} From b66367bc4b2e37294e6df3a933b5d2712ced0da6 Mon Sep 17 00:00:00 2001 From: THEPAUT Date: Wed, 19 Apr 2023 04:05:30 -0400 Subject: [PATCH 389/447] (plugin) notification::email - init new plugin (#4344) --- src/notification/email/mode/alert.pm | 1161 ++++++++++++++++++++++++++ src/notification/email/plugin.pm | 47 ++ 2 files changed, 1208 insertions(+) create mode 100644 src/notification/email/mode/alert.pm create mode 100644 src/notification/email/plugin.pm diff --git a/src/notification/email/mode/alert.pm b/src/notification/email/mode/alert.pm new file mode 100644 index 000000000..20bea8f74 --- /dev/null +++ b/src/notification/email/mode/alert.pm @@ -0,0 +1,1161 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package notification::email::mode::alert; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use MIME::Base64; +use Email::MIME; +use Email::Sender::Simple qw(sendmail); +use Email::Sender::Transport::SMTP; +use JSON::XS; +use URI::Escape; +use centreon::plugins::http; + +my %color_host = ( + up => { + background => '#88B922', + text => '#FFFFFF' + }, + down => { + background => '#FF4A4A', + text => '#FFFFFF' + }, + unreachable => { + background => '#E0E0E0', + text => '#666666' + }, + acknowledgement => { + background => '#F5F1E9', + text => '#666666' + }, + downtimestart => { + background => '#F0E9F8', + text => '#666666' + }, + downtimeend => { + background => '#F0E9F8', + text => '#666666' + }, + downtimecanceled => { + background => '#F0E9F8', + text => '#666666' + } +); + +my %color_service = ( + ok => { + background => '#88B922', + text => '#FFFFFF' + }, + warning => { + background => '#FD9B27', + text => '#FFFFFF' + }, + critical => { + background => '#FF4A4A', + text => '#FFFFFF' + }, + unknown => { + background => '#E0E0E0', + text => '#FFFFFF' + }, + acknowledgement => { + background => '#F5F1E9', + text => '#666666' + }, + downtimestart => { + background => '#F0E9F8', + text => '#666666' + }, + downtimeend => { + background => '#F0E9F8', + text => '#666666' + }, + downtimecanceled => { + background => '#F0E9F8', + text => '#666666' + } +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'smtp-address:s' => { name => 'smtp_address' }, + 'smtp-port:s' => { name => 'smtp_port', default => '25' }, + 'smtp-user:s' => { name => 'smtp_user', default => undef }, + 'smtp-password:s' => { name => 'smtp_password' }, + 'smtp-nossl' => { name => 'no_ssl' }, + 'smtp-debug' => { name => 'smtp_debug' }, + 'to-address:s' => { name => 'to_address' }, + 'from-address:s' => { name => 'from_address' }, + 'host-id:s' => { name => 'host_id' }, + 'host-address:s' => { name => 'host_address'}, + 'host-name:s' => { name => 'host_name' }, + 'host-alias:s' => { name => 'host_alias'}, + 'host-state:s' => { name => 'host_state' }, + 'host-output:s' => { name => 'host_output' }, + 'host-attempts:s' => { name => 'host_attempts'}, + 'max-host-attempts:s' => { name => 'max_host_attempts'}, + 'host-duration:s' => { name => 'host_duration' }, + 'service-id:s' => { name => 'service_id' }, + 'service-description:s' => { name => 'service_description' }, + 'service-state:s' => { name => 'service_state' }, + 'service-output:s' => { name => 'service_output' }, + 'service-longoutput:s' => { name => 'service_longoutput' }, + 'service-attempts:s' => { name => 'service_attempts'}, + 'max-service-attempts:s' => { name => 'max_service_attempts'}, + 'service-duration:s' => { name => 'service_duration' }, + 'centreon-user:s' => { name => 'centreon_user' }, + 'centreon-token:s' => { name => 'centreon_tooken' }, + 'date:s' => { name => 'date' }, + 'notif-author:s' => { name => 'notif_author'}, + 'notif-comment:s' => { name => 'notif_comment' }, + 'centreon-url:s' => { name => 'centreon_url' }, + 'centreon-token:s' => { name => 'centreon_token' }, + 'type:s' => { name => 'type' }, + 'timeout:s' => { name => 'timeout', default => 10 } + }); + + $self->{payload_attachment} = { 'subject' => undef, 'alt_message' => undef, 'html_message' => undef , 'png' => undef }; + + $self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl'); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{to_address}) || $self->{option_results}->{to_address} eq '') { + $self->{output}->add_option_msg(short_msg => "You need to specify --to-address option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{host_name}) || $self->{option_results}->{host_name} eq '') { + $self->{output}->add_option_msg(short_msg => "You need to specify --host-name option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{smtp_address}) || $self->{option_results}->{smtp_address} eq '') { + $self->{output}->add_option_msg(short_msg => "You need to specify --smtp-address option."); + $self->{output}->option_exit(); + } + + $self->{smtp_ssl} = defined($self->{option_results}->{no_ssl}) ? 0 : 'starttls'; + $self->{smtp_debug} = defined($self->{option_results}->{smtp_debug}) ? 1 : 0; + $self->{smtp_user} = defined($self->{option_results}->{smtp_user}) && $self->{option_results}->{smtp_user} ne '' + ? $self->{option_results}->{smtp_user} : ''; + $self->{smtp_password} = defined($self->{option_results}->{smtp_password}) && $self->{option_results}->{smtp_password} ne '' + ? $self->{option_results}->{smtp_password} : ''; + + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub host_message { + my ($self, %options) = @_; + + my $host_id = $self->{option_results}->{host_id}; + + my $details = { + id => $host_id, + resourcesDetailsEndpoint => "/centreon/api/latest/monitoring/resources/hosts/$host_id", + tab => "details" + }; + + my $author_html = ''; + my $author_alt = ''; + my $comment_html = ''; + my $comment_alt = ''; + if (defined($self->{option_results}->{notif_author}) && $self->{option_results}->{notif_author} ne '') { + if ($self->{option_results}->{type} =~ /^downtime.*$/i) { + $author_html = '

                  Scheduled Downtime by:

                  +

                  ' . $self->{option_results}->{notif_author} . '

                  '; + $author_alt = 'Scheduled Downtime by: ' . $self->{option_results}->{notif_author}; + } elsif ($self->{option_results}->{type} =~ /^acknowledgement$/i) { + $author_html = '

                  Acknowledged Author:

                  +

                  ' . $self->{option_results}->{notif_author} . '

                  '; + $author_alt = 'Acknowledged Author: ' . $self->{option_results}->{notif_author}; + } elsif ($self->{option_results}->{type} =~ /^flaping.*$/i) { + $author_html = '

                  Flapping Author:

                  +

                  ' . $self->{option_results}->{notif_author} . '

                  '; + $author_alt = 'Flapping Author: ' . $self->{option_results}->{notif_author}; + } + } + + if (defined($self->{option_results}->{notif_comment}) && $self->{option_results}->{notif_comment} ne '') { + if ($self->{option_results}->{type} =~ /^downtime.*$/i){ + $comment_html = '

                  Scheduled Downtime Comment:

                  +

                  ' . $self->{option_results}->{notif_comment} . '

                  '; + $comment_alt = 'Scheduled Downtime Comment: ' . $self->{option_results}->{notif_comment}; + } elsif ($self->{option_results}->{type} =~ /^acknowledgement$/i) { + $comment_html = '

                  Acknowledged Comment:

                  +

                  ' . $self->{option_results}->{notif_comment} . '

                  '; + $comment_alt = 'Acknowledged Comment: ' . $self->{option_results}->{notif_comment}; + } elsif ($self->{option_results}->{type} =~ /^flaping.*$/i) { + $comment_html = '

                  Flapping Comment:

                  +

                  ' . $self->{option_results}->{notif_comment} . '

                  '; + $comment_alt = 'Flapping Comment: ' . $self->{option_results}->{notif_comment}; + } + } + + my $json_data = encode_json($details); + my $encoded_data = uri_escape($json_data); + + $self->{payload_attachment}->{subject} = '*** ' . $self->{option_results}->{type} . ' : Host: ' . $self->{option_results}->{host_name} . ' ' . $self->{option_results}->{host_state} . ' ***'; + $self->{payload_attachment}->{alt_message} = ' + ***** Centreon ***** + + Notification Type: ' . $self->{option_results}->{type} . ' + Hostname: ' . $self->{option_results}->{host_name} . ' + Hostalias: ' . $self->{option_results}->{host_alias} . ' + State: ' . $self->{option_results}->{host_state} . ' + Address: ' . $self->{option_results}->{host_address} . ' + Date/Time: ' . $self->{option_results}->{date}; + + if(defined($author_alt) && $author_alt ne ''){ + $self->{payload_attachment}->{alt_message} .= "\n " . $author_alt . "\n"; + } + if(defined($comment_alt) && $comment_alt ne ''){ + $self->{payload_attachment}->{alt_message} .= " " . $comment_alt . "\n"; + } + $self->{payload_attachment}->{alt_message} .= ' + + Info: + ' .$self->{option_results}->{host_output}; + + $self->{payload_attachment}->{html_message} = ' + + + + + ' . $self->{option_results}->{host_name} . ' + + + + + + + + + + + + + +
                  + +
                  + [' .$self->{option_results}->{type} . '] Host: ' . $self->{option_results}->{host_alias} . ' (' . $self->{option_results}->{host_name} . ') is ' . $self->{option_results}->{host_state} . '. *************************************************************************************************************************************** +
                  + + + +
                  + + + '; +} + +sub service_message { + my ($self, %options) = @_; + + my $host_id = $self->{option_results}->{host_id}; + my $service_id = $self->{option_results}->{service_id}; + + my $author_html = ''; + my $author_alt = ''; + my $comment_html = ''; + my $comment_alt = ''; + if (defined($self->{option_results}->{notif_author}) && $self->{option_results}->{notif_author} ne '') { + if ($self->{option_results}->{type} =~ /^downtime.*$/i) { + $author_html = '

                  Scheduled Downtime by:

                  +

                  ' . $self->{option_results}->{notif_author} . '

                  '; + $author_alt = 'Scheduled Downtime by: ' . $self->{option_results}->{notif_author}; + } elsif($self->{option_results}->{type} =~ /^acknowledgement$/i) { + $author_html = '

                  Acknowledged Author:

                  +

                  ' . $self->{option_results}->{notif_author} . '

                  '; + $author_alt = 'Acknowledged Author: ' . $self->{option_results}->{notif_author}; + } elsif($self->{option_results}->{type} =~ /^flaping.*$/i) { + $author_html = '

                  Flapping Author:

                  +

                  ' . $self->{option_results}->{notif_author} . '

                  '; + $author_alt = 'Flapping Author: ' . $self->{option_results}->{notif_author}; + } + } + + if (defined($self->{option_results}->{notif_comment}) && $self->{option_results}->{notif_comment} ne '') { + if ($self->{option_results}->{type} =~ /^downtime.*$/i) { + $comment_html = '

                  Scheduled Downtime Comment:

                  +

                  ' . $self->{option_results}->{notif_comment} . '

                  '; + $comment_alt = 'Scheduled Downtime Comment: ' . $self->{option_results}->{notif_comment}; + } elsif($self->{option_results}->{type} =~ /^acknowledgement$/i) { + $comment_html = '

                  Acknowledged Comment:

                  +

                  ' . $self->{option_results}->{notif_comment} . '

                  '; + $comment_alt = 'Acknowledged Comment: ' . $self->{option_results}->{notif_comment}; + } elsif($self->{option_results}->{type} =~ /^flaping.*$/i) { + $comment_html = '

                  Flapping Comment:

                  +

                  ' . $self->{option_results}->{notif_comment} . '

                  '; + $comment_alt = 'Flapping Comment: ' . $self->{option_results}->{notif_comment}; + } + } + + my $content = $self->{http}->request( + hostname => '', + full_url => $self->{option_results}->{centreon_url} . '/centreon/include/views/graphs/generateGraphs/generateImage.php?akey=' . $self->{option_results}->{centreon_token} . '&username=' . $self->{option_results}->{centreon_user} . '&hostname=' . $self->{option_results}->{host_name} . '&service='. $self->{option_results}->{service_description}, + timeout => $self->{option_results}->{timeout}, + unknown_status => '', + warning_status => '', + critical_status => '' + ); + + my $img; + if ($self->{http}->get_code() !~ /200/ || $content =~ /^OK/) { + $img = '

                  No graph

                  '; + } else { + $self->{payload_attachment}->{png} = $content; + $img = '\n"; + } + + my $details = { + id => $service_id, + resourcesDetailsEndpoint => "/centreon/api/latest/monitoring/resources/hosts/$host_id/services/$service_id", + tab => 'details' + }; + + my $json_data = encode_json($details); + my $encoded_data = uri_escape($json_data); + + my $line_break = '
                  '; + + $self->{option_results}->{service_longoutput} =~ s/\n/
                  /g; + + $self->{payload_attachment}->{subject} = '*** ' . $self->{option_results}->{type} . ' : ' . $self->{option_results}->{service_description} . ' '. $self->{option_results}->{service_state} . ' on ' . $self->{option_results}->{host_name} . ' ***'; + $self->{payload_attachment}->{alt_message} = ' + ***** Centreon ***** + + Notification Type: ' . $self->{option_results}->{type} . ' + Service: ' . $self->{option_results}->{service_description} . ' + Hostname: ' . $self->{option_results}->{host_name} . ' + Hostalias: ' . $self->{option_results}->{host_alias} . ' + State: ' . $self->{option_results}->{service_state} . ' + Address: ' . $self->{option_results}->{host_address} . ' + Date/Time: ' .$self->{option_results}->{date}; + + if (defined($author_alt) && $author_alt ne '') { + $self->{payload_attachment}->{alt_message} .= "\n " . $author_alt . "\n"; + } + if(defined($comment_alt) && $comment_alt ne '') { + $self->{payload_attachment}->{alt_message} .= " " . $comment_alt . "\n"; + } + $self->{payload_attachment}->{alt_message} .= ' + + Info: + ' . $self->{option_results}->{service_output} . ' + ' . $self->{option_results}->{service_longoutput}; + + $self->{payload_attachment}->{html_message} = ' + + + + + ' . $self->{option_results}->{host_name} . ' / ' . $self->{option_results}->{service_description} .' + + + + + + + + + + + + + +
                  + +
                  [' . $self->{option_results}->{type} . '] Service: ' . $self->{option_results}->{service_description} . ' on Host: ' . $self->{option_results}->{host_name} . ' (' . $self->{option_results}->{host_alias} . ') is '. $self->{option_results}->{service_state} . '. *************************************************************************************************************************************** +
                  + + +
                  + + + '; +} + +sub set_payload { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{service_description}) && $self->{option_results}->{service_description} ne '') { + $self->service_message(); + } else { + $self->host_message(); + } +} + +sub run { + my ($self, %options) = @_; + + $self->set_payload(); + my $attachement = ''; + if (defined($self->{payload_attachment}->{png}) && $self->{payload_attachment}->{png} ne '' && $self->{payload_attachment}->{png} ne 'Resource not found' ) { + my $img_cid = $self->{option_results}->{host_name} . '_' . $self->{option_results}->{service_description}; + $attachement = Email::MIME->create( + header_str => [ + 'Content-ID' => "<$img_cid>" + ], + attributes => { + content_type => 'image/png', + disposition => 'inline', + encoding => 'base64', + name => $self->{option_results}->{host_name} . ' - ' . $self->{option_results}->{service_description} . '.png' + }, + body => $self->{payload_attachment}->{png} + ); + } + + my $email = Email::MIME->create( + header_str => [ + From => $self->{option_results}->{from_address}, + To => $self->{option_results}->{to_address}, + Subject => $self->{payload_attachment}->{subject} + ], + parts => [ + Email::MIME->create( + attributes => { + content_type => 'text/plain', + charset => 'UTF-8' + }, + body => $self->{payload_attachment}->{alt_message} + ), + Email::MIME->create( + attributes => { + content_type => 'text/html', + charset => 'UTF-8' + }, + body => $self->{payload_attachment}->{html_message} + ), + $attachement + ] + ); + + my $smtp = Email::Sender::Transport::SMTP->new({ + host => $self->{option_results}->{smtp_address}, + port => $self->{option_results}->{smtp_port}, + sasl_username => $self->{smtp_user}, + sasl_password => $self->{smtp_password}, + ssl => $self->{smtp_ssl}, + debug => $self->{smtp_debug} + }); + + eval { sendmail($email, { transport => $smtp }); }; + if ($@) { + $self->{output}->output_add(long_msg => 'SMTP Error: ' . $@); + } else { + $self->{output}->output_add(short_msg => 'Email sent'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Send Email alerts. + +Example for a host: + +centreon_plugins.pl --plugin=notification::email::plugin --mode=alert --to-address='john.doe@example.com' --host-address='192.168.1.1' --host-name='webserver' --host-alias='Web Server' --host-state='DOWN' --host-output='CRITICAL - Socket timeout after 10 seconds' --host-attempts='3' --max-host-attempts='3' --host-duration='6d 18h 33m 51s' --date='2023-04-12 10:30:00' --type='PROBLEM' --service-description='' --service-state='' --service-output='' --service-longoutput='' --service-attempts='' --max-service-attempts='' --service-duration='' --host-id='123' --service-id='' --notif-author='' --notif-comment='' --smtp-nossl --centreon-url='https://your-centreon-server' --smtp-address='smtp.example.com' --smtp-port='587' --from-address='centreon-engine@centreon.com' --centreon-user='admin' --centreon-token='Toi5Ve7ie' --smtp-user='john.doe@example.com' --smtp-password='mysecret' + +Example for a service: + +centreon_plugins.pl --plugin=notification::email::plugin --mode=alert --to-address='user@example.com' --host-address='192.168.1.100' --host-name='server1' --host-alias='Web Server' --host-state='UP' --host-output='OK - 192.168.1.1 rta 59.377ms lost 0%' --host-attempts='1' --max-host-attempts='3' --host-duration='41d 10h 5m 18s' --date='2023-04-12 14:30:00' --type='PROBLEM' --service-description='HTTP' --service-state='CRITICAL' --service-output='Connection timed out' --service-longoutput='Check HTTP failed: Connection timed out' --service-attempts='3' --max-service-attempts='3' --service-duration='0d 0h 0m 18s' --host-id='100' --service-id='200' --notif-author='' --notif-comment='' --smtp-nossl --centreon-url='https://your-centreon-server' --smtp-address='smtp.example.com' --smtp-port='587' --from-address='centreon@example.com' --centreon-user='admin' --centreon-token='myauthtoken' --smtp-user='johndoe@example.com' --smtp-password='mypassword' + +Example for Centreon configuration: + +centreon_plugins.pl --plugin=notification::email::plugin --mode=alert --to-address='$CONTACTEMAIL$' --host-address='$HOSTADDRESS$' --host-name='$HOSTNAME$' --host-alias='$HOSTALIAS$' --host-state='$HOSTSTATE$' --host-output='$HOSTOUTPUT$' --host-attempts='$HOSTATTEMPT$' --max-host-attempts='$MAXHOSTATTEMPTS$' --host-duration='$HOSTDURATION$' --date='$SHORTDATETIME$' --type='$NOTIFICATIONTYPE$' --service-description='$SERVICEDESC$' --service-state='$SERVICESTATE$' --service-output='$SERVICEOUTPUT$' --service-longoutput='$LONGSERVICEOUTPUT$' --service-attempts=''$SERVICEATTEMPT$ --max-service-attempts='$MAXSERVICEATTEMPTS$' --service-duration='$SERVICEDURATION$' --host-id='$HOSTID$' --service-id='$SERVICEID$' --notif-author='$NOTIFICATIONAUTHOR$' --notif-comment='$NOTIFICATIONCOMMENT$' --smtp-nossl --centreon-url='https://your-centreon-server' --smtp-address=your-smtp-server --smtp-port=your-smtp-port --from-address='centreon-engine@centreon.com' --centreon-user='your-centreon-username' --centreon-token='your-centreon-autologin-key' --smtp-user='your-smtp-username' --smtp-password='your-smtp-password' + +=over 8 + +=item B<--smtp-address> + +SMTP server address. + +=item B<--smtp-port> + +SMTP server port (default: 25). + +=item B<--smtp-user> + +SMTP server username. + +=item B<--smtp-password> + +SMTP server password. + +=item B<--smtp-nossl> + +Use this option to disable SSL. + +=item B<--smtp-debug> + +Enable smtp-debug mode. + +=item B<--to-address> + +Email address of the recipient (Required). + +=item B<--from-address> + +Email address of the sender (Required). + +=item B<--host-id> + +ID of the host. + +=item B<--host-address> + +IP Address of the host. + +=item B<--host-name> + +Name of the host. + +=item B<--host-alias> + +Alias of the host. + +=item B<--host-state> + +State of the host. + +=item B<--host-output> + +Output of the host. + +=item B<--host-attempts> + +Number of attempts made before HARD to check the host. + +=item B<--max-host-attempts> + +Number of attempts made before host HARD state. + +=item B<--host-duration> + +Duration of the host status. + +=item B<--service-id> + +ID of the service. + +=item B<--service-description> + +Description of the service. + +=item B<--service-state> + +State of the service. + +=item B<--service-output> + +Output of the service. + +=item B<--service-longoutput> + +Long output of the service. + +=item B<--service-attempts> + +Number of attempts made to check the service. + +=item B<--max-service-attempts> + +Number of attempts made before service HARD state. + +=item B<--service-duration> + +Duration of the service status. + +=item B<--centreon-user> + +Username for the Centreon web interface. + +=item B<--centreon-token> + +Token for the Centreon web interface (autologin). + +=item B<--date> + +Date of the alert. + +=item B<--notif-author> + +Author of the notification. + +=item B<--notif-comment> + +Comment for the notification. + +=item B<--centreon-url> + +URL of the Centreon web interface. Use either HTTP or HTTPS protocol depending on your setup, for example: +--centreon-url='http://your-centreon-server' +--centreon-url='https://your-centreon-server' + +=item B<--type> + +Type of the alert. + +=item B<--timeout> + +Timeout for the request (default: 10 seconds). + +=back + +=back + +=cut diff --git a/src/notification/email/plugin.pm b/src/notification/email/plugin.pm new file mode 100644 index 000000000..88937b121 --- /dev/null +++ b/src/notification/email/plugin.pm @@ -0,0 +1,47 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package notification::email::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'alert' => 'notification::email::mode::alert' + }; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Send E-Mail notifications. + +=cut From a4d0c3c1b7f61be9775f4159bb7acd5c246ba1f3 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 19 Apr 2023 10:27:08 +0200 Subject: [PATCH 390/447] (plugin) apps::protocols::x509 - add support for verify_hostname (#4364) --- src/apps/protocols/x509/custom/tcp.pm | 15 +++++++++++++++ src/apps/protocols/x509/mode/certificate.pm | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/apps/protocols/x509/custom/tcp.pm b/src/apps/protocols/x509/custom/tcp.pm index ecc61f1e9..c60d05238 100644 --- a/src/apps/protocols/x509/custom/tcp.pm +++ b/src/apps/protocols/x509/custom/tcp.pm @@ -209,6 +209,21 @@ sub get_certificate_informations { $cert_infos->{subject} = $socket->peer_certificate('commonName'); $cert_infos->{issuer} = $socket->peer_certificate('authority'); + if (defined($self->{ssl_context}->{SSL_verify_mode}) && + defined($self->{option_results}->{servername}) && + $self->{ssl_context}->{SSL_verify_mode} == SSL_VERIFY_NONE) { + $cert_infos->{verify_hostname} = $socket->verify_hostname( + $self->{option_results}->{servername}, + # like default scheme + { + wildcards_in_cn => 'anywhere', + wildcards_in_alt => 'anywhere', + check_cn => 'always', + ip_in_cn => 1, + } + ); + } + my @subject_alt_names = $socket->peer_certificate('subjectAltNames'); my $append = ''; $cert_infos->{alt_subjects} = ''; diff --git a/src/apps/protocols/x509/mode/certificate.pm b/src/apps/protocols/x509/mode/certificate.pm index 6c12bbc49..2070ced3c 100644 --- a/src/apps/protocols/x509/mode/certificate.pm +++ b/src/apps/protocols/x509/mode/certificate.pm @@ -34,9 +34,15 @@ sub custom_status_output { $self->{result_values}->{subject}, $self->{result_values}->{expiration}, $self->{result_values}->{date}, $self->{result_values}->{issuer} ); + if (defined($self->{result_values}->{verify_hostname}) && $self->{result_values}->{verify_hostname} eq 'FAILED') { + $msg .= sprintf(" - Verify hostname status '%s'", $self->{result_values}->{verify_hostname}); + } if (defined($self->{result_values}->{alt_subjects}) && $self->{result_values}->{alt_subjects} ne '') { $self->{output}->output_add(long_msg => sprintf("Alternative subject names: %s.", $self->{result_values}->{alt_subjects})); } + if (defined($self->{result_values}->{verify_hostname}) && $self->{result_values}->{verify_hostname} ne '-') { + $self->{output}->output_add(long_msg => sprintf("Verify hostname result: %s.", $self->{result_values}->{verify_hostname})); + } return $msg; } @@ -48,6 +54,7 @@ sub custom_status_calc { $self->{result_values}->{expiration} = ($options{new_datas}->{$self->{instance} . '_expiration'} - time()) / 86400; $self->{result_values}->{date} = $options{new_datas}->{$self->{instance} . '_date'}; $self->{result_values}->{alt_subjects} = $options{new_datas}->{$self->{instance} . '_alt_subjects'}; + $self->{result_values}->{verify_hostname} = $options{new_datas}->{$self->{instance} . '_verify_hostname'}; return 0; } @@ -63,11 +70,13 @@ sub set_counters { label => 'status', type => 2, warning_default => '%{expiration} < 60', critical_default => '%{expiration} < 30', + unknown_default => '%{verify_hostname} eq "FAILED"', set => { key_values => [ { name => 'subject' }, { name => 'issuer' }, { name => 'expiration' }, { name => 'date' }, - { name => 'alt_subjects' } + { name => 'alt_subjects' }, + { name => 'verify_hostname' }, ], closure_custom_calc => $self->can('custom_status_calc'), closure_custom_output => $self->can('custom_status_output'), @@ -99,7 +108,9 @@ sub manage_selection { issuer => defined($cert->{issuer}) ? $cert->{issuer} : '-', expiration => $cert->{expiration}, date => $cert->{expiration_date}, - alt_subjects => $cert->{alt_subjects} + alt_subjects => $cert->{alt_subjects}, + verify_hostname => defined($cert->{verify_hostname}) + ? ($cert->{verify_hostname} ? "OK" : "FAILED") : '-', }; } From 326929d341e53ef311dce784f6a7772c01455606 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 19 Apr 2023 13:11:53 +0200 Subject: [PATCH 391/447] (plugin) cloud::azure::database::sqldatabase - fix --server option (#4366) --- src/cloud/azure/database/sqldatabase/mode/connections.pm | 4 +++- src/cloud/azure/database/sqldatabase/mode/deadlocks.pm | 2 ++ src/cloud/azure/database/sqldatabase/mode/sessions.pm | 4 +++- src/cloud/azure/database/sqldatabase/mode/storage.pm | 4 +++- src/cloud/azure/database/sqldatabase/mode/workers.pm | 4 +++- src/cloud/azure/database/sqldatabase/plugin.pm | 7 +++---- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/cloud/azure/database/sqldatabase/mode/connections.pm b/src/cloud/azure/database/sqldatabase/mode/connections.pm index 40cfd3401..431e59cf7 100644 --- a/src/cloud/azure/database/sqldatabase/mode/connections.pm +++ b/src/cloud/azure/database/sqldatabase/mode/connections.pm @@ -87,6 +87,8 @@ sub check_options { $resource_group = $1; $server = $2; $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; } $self->{az_resource} = $resource; @@ -165,4 +167,4 @@ Critical threshold where '*' can be: 'connection-failed', 'connection-successfu =back -=cut \ No newline at end of file +=cut diff --git a/src/cloud/azure/database/sqldatabase/mode/deadlocks.pm b/src/cloud/azure/database/sqldatabase/mode/deadlocks.pm index 9bf4283b2..cc5d65ccf 100644 --- a/src/cloud/azure/database/sqldatabase/mode/deadlocks.pm +++ b/src/cloud/azure/database/sqldatabase/mode/deadlocks.pm @@ -71,6 +71,8 @@ sub check_options { $resource_group = $1; $server = $2; $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; } $self->{az_resource} = $resource; diff --git a/src/cloud/azure/database/sqldatabase/mode/sessions.pm b/src/cloud/azure/database/sqldatabase/mode/sessions.pm index 444932c2d..69463fed1 100644 --- a/src/cloud/azure/database/sqldatabase/mode/sessions.pm +++ b/src/cloud/azure/database/sqldatabase/mode/sessions.pm @@ -71,6 +71,8 @@ sub check_options { $resource_group = $1; $server = $2; $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; } $self->{az_resource} = $resource; @@ -148,4 +150,4 @@ Critical threshold. =back -=cut \ No newline at end of file +=cut diff --git a/src/cloud/azure/database/sqldatabase/mode/storage.pm b/src/cloud/azure/database/sqldatabase/mode/storage.pm index 0ccc097e5..c3cf70adf 100644 --- a/src/cloud/azure/database/sqldatabase/mode/storage.pm +++ b/src/cloud/azure/database/sqldatabase/mode/storage.pm @@ -79,6 +79,8 @@ sub check_options { $resource_group = $1; $server = $2; $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; } $self->{az_resource} = $resource; @@ -156,4 +158,4 @@ Critical threshold where '*' can be: 'usage-bytes','usage-percent'. =back -=cut \ No newline at end of file +=cut diff --git a/src/cloud/azure/database/sqldatabase/mode/workers.pm b/src/cloud/azure/database/sqldatabase/mode/workers.pm index 9b754767d..d06be415c 100644 --- a/src/cloud/azure/database/sqldatabase/mode/workers.pm +++ b/src/cloud/azure/database/sqldatabase/mode/workers.pm @@ -71,6 +71,8 @@ sub check_options { $resource_group = $1; $server = $2; $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; } $self->{az_resource} = $resource; @@ -148,4 +150,4 @@ Critical threshold. =back -=cut \ No newline at end of file +=cut diff --git a/src/cloud/azure/database/sqldatabase/plugin.pm b/src/cloud/azure/database/sqldatabase/plugin.pm index f6623465a..04489aac8 100644 --- a/src/cloud/azure/database/sqldatabase/plugin.pm +++ b/src/cloud/azure/database/sqldatabase/plugin.pm @@ -29,8 +29,7 @@ sub new { my $self = $class->SUPER::new( package => __PACKAGE__, %options ); bless $self, $class; - $self->{version} = '0.1'; - %{ $self->{modes} } = ( + $self->{modes} = { 'app-resources' => 'cloud::azure::database::sqldatabase::mode::appresources', 'connections' => 'cloud::azure::database::sqldatabase::mode::connections', 'discovery' => 'cloud::azure::database::sqldatabase::mode::discovery', @@ -39,7 +38,7 @@ sub new { 'sessions' => 'cloud::azure::database::sqldatabase::mode::sessions', 'storage' => 'cloud::azure::database::sqldatabase::mode::storage', 'workers' => 'cloud::azure::database::sqldatabase::mode::workers' - ); + }; $self->{custom_modes}->{azcli} = 'cloud::azure::custom::azcli'; $self->{custom_modes}->{api} = 'cloud::azure::custom::api'; @@ -50,7 +49,7 @@ sub init { my ($self, %options) = @_; $self->{options}->add_options(arguments => { - 'api-version:s' => { name => 'api_version', default => '2018-01-01' }, + 'api-version:s' => { name => 'api_version', default => '2018-01-01' } }); $self->SUPER::init(%options); From 954742ed7ae8aa61facf71744eefa5a183c2c345 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 19 Apr 2023 13:41:15 +0200 Subject: [PATCH 392/447] (plugin) storage::emc::unisphere::restapi - mode hardware add component memmodule (#4367) --- .../restapi/mode/components/battery.pm | 6 +- .../unisphere/restapi/mode/components/disk.pm | 4 +- .../unisphere/restapi/mode/components/dpe.pm | 4 +- .../unisphere/restapi/mode/components/fan.pm | 4 +- .../restapi/mode/components/iomodule.pm | 4 +- .../restapi/mode/components/memmodule.pm | 65 +++++++++++++++++++ .../unisphere/restapi/mode/components/psu.pm | 4 +- .../unisphere/restapi/mode/components/sp.pm | 2 +- .../unisphere/restapi/mode/components/ssd.pm | 2 +- .../emc/unisphere/restapi/mode/hardware.pm | 10 +-- 10 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 src/storage/emc/unisphere/restapi/mode/components/memmodule.pm diff --git a/src/storage/emc/unisphere/restapi/mode/components/battery.pm b/src/storage/emc/unisphere/restapi/mode/components/battery.pm index 1549d0258..ec89ae5e0 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/battery.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/battery.pm @@ -47,11 +47,11 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "battery '%s' status is '%s' [instance = %s]", - $result->{content}->{name}, $health, $instance, + "battery '%s' status is '%s' [instance: %s]", + $result->{content}->{name}, $health, $instance ) ); - + my $exit = $self->get_severity(label => 'health', section => 'battery', value => $health); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( diff --git a/src/storage/emc/unisphere/restapi/mode/components/disk.pm b/src/storage/emc/unisphere/restapi/mode/components/disk.pm index 848469d40..7ebce24c7 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/disk.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/disk.pm @@ -47,8 +47,8 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "disk '%s' status is '%s' [instance = %s]", - $result->{content}->{name}, $health, $instance, + "disk '%s' status is '%s' [instance: %s]", + $result->{content}->{name}, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/components/dpe.pm b/src/storage/emc/unisphere/restapi/mode/components/dpe.pm index be7a4a672..5950bf8c5 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/dpe.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/dpe.pm @@ -47,8 +47,8 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "dpe '%s' status is '%s' [instance = %s]", - $result->{content}->{name}, $health, $instance, + "dpe '%s' status is '%s' [instance: %s]", + $result->{content}->{name}, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/components/fan.pm b/src/storage/emc/unisphere/restapi/mode/components/fan.pm index 5a450c0d4..950133da5 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/fan.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/fan.pm @@ -47,8 +47,8 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "fan '%s' status is '%s' [instance = %s]", - $result->{content}->{id}, $health, $instance, + "fan '%s' status is '%s' [instance: %s]", + $result->{content}->{id}, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/components/iomodule.pm b/src/storage/emc/unisphere/restapi/mode/components/iomodule.pm index 5213d5e4c..3f6a5c617 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/iomodule.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/iomodule.pm @@ -47,8 +47,8 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "iomodule '%s' status is '%s' [instance = %s]", - $result->{content}->{name}, $health, $instance, + "iomodule '%s' status is '%s' [instance: %s]", + $result->{content}->{name}, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/components/memmodule.pm b/src/storage/emc/unisphere/restapi/mode/components/memmodule.pm new file mode 100644 index 000000000..382b12361 --- /dev/null +++ b/src/storage/emc/unisphere/restapi/mode/components/memmodule.pm @@ -0,0 +1,65 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::unisphere::restapi::mode::components::memmodule; + +use strict; +use warnings; +use storage::emc::unisphere::restapi::mode::components::resources qw($health_status); + +sub load { + my ($self) = @_; + + $self->{json_results}->{memmodules} = $self->{custom}->request_api(method => 'GET', url_path => '/api/types/memoryModule/instances?fields=name,health'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => 'checking memmodules'); + $self->{components}->{memmodule} = { name => 'memmodules', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'memmodule')); + return if (!defined($self->{json_results}->{memmodules})); + + foreach my $result (@{$self->{json_results}->{memmodules}->{entries}}) { + my $instance = $result->{content}->{id}; + + next if ($self->check_filter(section => 'memmodule', instance => $instance)); + $self->{components}->{memmodule}->{total}++; + + my $health = $health_status->{ $result->{content}->{health}->{value} }; + $self->{output}->output_add( + long_msg => sprintf( + "memory module '%s' status is '%s' [instance: %s]", + $result->{content}->{name}, $health, $instance + ) + ); + + my $exit = $self->get_severity(label => 'health', section => 'memmodule', value => $health); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("memory module '%s' status is '%s'", $result->{content}->{name}, $health) + ); + } + } +} + +1; diff --git a/src/storage/emc/unisphere/restapi/mode/components/psu.pm b/src/storage/emc/unisphere/restapi/mode/components/psu.pm index 2655a7f1f..c5f557f02 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/psu.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/psu.pm @@ -47,8 +47,8 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "power supply '%s' status is '%s' [instance = %s]", - $result->{content}->{name}, $health, $instance, + "power supply '%s' status is '%s' [instance: %s]", + $result->{content}->{name}, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/components/sp.pm b/src/storage/emc/unisphere/restapi/mode/components/sp.pm index 611b35d59..a6614cf7a 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/sp.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/sp.pm @@ -48,7 +48,7 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "storage processor '%s' status is '%s' [instance = %s]", + "storage processor '%s' status is '%s' [instance: %s]", $name, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/components/ssd.pm b/src/storage/emc/unisphere/restapi/mode/components/ssd.pm index 55fe80490..b7380aa7b 100644 --- a/src/storage/emc/unisphere/restapi/mode/components/ssd.pm +++ b/src/storage/emc/unisphere/restapi/mode/components/ssd.pm @@ -48,7 +48,7 @@ sub check { my $health = $health_status->{ $result->{content}->{health}->{value} }; $self->{output}->output_add( long_msg => sprintf( - "ssd '%s' status is '%s' [instance = %s]", + "ssd '%s' status is '%s' [instance: %s]", $name, $health, $instance ) ); diff --git a/src/storage/emc/unisphere/restapi/mode/hardware.pm b/src/storage/emc/unisphere/restapi/mode/hardware.pm index 7802770e0..263b1d5ce 100644 --- a/src/storage/emc/unisphere/restapi/mode/hardware.pm +++ b/src/storage/emc/unisphere/restapi/mode/hardware.pm @@ -41,12 +41,12 @@ sub set_system { ['major', 'CRITICAL'], ['critical', 'CRITICAL'], ['non_recoverable', 'CRITICAL'], - ['unknown', 'UNKNOWN'], - ], + ['unknown', 'UNKNOWN'] + ] }; - + $self->{components_path} = 'storage::emc::unisphere::restapi::mode::components'; - $self->{components_module} = ['disk', 'fan', 'iomodule', 'psu', 'dpe', 'battery', 'ssd', 'sp']; + $self->{components_module} = ['disk', 'fan', 'iomodule', 'memmodule', 'psu', 'dpe', 'battery', 'ssd', 'sp']; } sub new { @@ -76,7 +76,7 @@ Check hardware. =item B<--component> Which component to check (Default: '.*'). -Can be: 'disk', 'fan', 'iomodule', 'psu', 'dpe', 'battery', 'ssd', 'sp'. +Can be: 'disk', 'fan', 'iomodule', 'memmodule', 'psu', 'dpe', 'battery', 'ssd', 'sp'. =item B<--filter> From 3de4cf4e69d65b189c1c3505b50a5da4127dd7f5 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 19 Apr 2023 13:48:57 +0200 Subject: [PATCH 393/447] (plugin) cloud::azure::database::postgres - new (#4365) --- .../deb.json | 5 + .../pkg.json | 10 + .../rpm.json | 6 + .../database/postgres/mode/connections.pm | 175 +++++++++++++++++ src/cloud/azure/database/postgres/mode/cpu.pm | 154 +++++++++++++++ .../azure/database/postgres/mode/discovery.pm | 145 ++++++++++++++ .../database/postgres/mode/ioconsumption.pm | 154 +++++++++++++++ .../azure/database/postgres/mode/memory.pm | 154 +++++++++++++++ .../database/postgres/mode/replication.pm | 160 ++++++++++++++++ .../azure/database/postgres/mode/storage.pm | 181 ++++++++++++++++++ .../azure/database/postgres/mode/traffic.pm | 156 +++++++++++++++ src/cloud/azure/database/postgres/plugin.pm | 66 +++++++ 12 files changed, 1366 insertions(+) create mode 100644 packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/deb.json create mode 100644 packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/pkg.json create mode 100644 packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/rpm.json create mode 100644 src/cloud/azure/database/postgres/mode/connections.pm create mode 100644 src/cloud/azure/database/postgres/mode/cpu.pm create mode 100644 src/cloud/azure/database/postgres/mode/discovery.pm create mode 100644 src/cloud/azure/database/postgres/mode/ioconsumption.pm create mode 100644 src/cloud/azure/database/postgres/mode/memory.pm create mode 100644 src/cloud/azure/database/postgres/mode/replication.pm create mode 100644 src/cloud/azure/database/postgres/mode/storage.pm create mode 100644 src/cloud/azure/database/postgres/mode/traffic.pm create mode 100644 src/cloud/azure/database/postgres/plugin.pm diff --git a/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/deb.json b/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/deb.json new file mode 100644 index 000000000..8133a85e5 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libdatetime-perl" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/pkg.json b/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/pkg.json new file mode 100644 index 000000000..499323977 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/pkg.json @@ -0,0 +1,10 @@ +{ + "pkg_name": "centreon-plugin-Cloud-Azure-Database-Postgres-Api", + "pkg_summary": "Centreon Plugin to monitor Microsoft Azure Database for Postgres service using CLI or RestAPI", + "plugin_name": "centreon_azure_database_postgres_api.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "cloud/azure/custom/", + "cloud/azure/database/postgres/" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/rpm.json b/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/rpm.json new file mode 100644 index 000000000..4db4877ce --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Azure-Database-Postgres-Api/rpm.json @@ -0,0 +1,6 @@ +{ + "dependencies": [ + "perl(DateTime)", + "perl(Digest::SHA)" + ] +} diff --git a/src/cloud/azure/database/postgres/mode/connections.pm b/src/cloud/azure/database/postgres/mode/connections.pm new file mode 100644 index 000000000..8ddd116d6 --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/connections.pm @@ -0,0 +1,175 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::connections; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'active_connections' => { + 'output' => 'Active Connections', + 'label' => 'connections-active', + 'nlabel' => 'azpostgres.connections.active.count', + 'unit' => '', + 'min' => '0' + }, + 'connections_failed' => { + 'output' => 'Failed Connections', + 'label' => 'connections-failed', + 'nlabel' => 'azpostgres.connections.failed.count', + 'unit' => '', + 'min' => '0' + }, + 'aborted_connections' => { + 'output' => 'Aborted Connections', + 'label' => 'connections-aborted', + 'nlabel' => 'azpostgres.connections.aborted.count', + 'unit' => '', + 'min' => '0' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + my $resource_mapping = { + 'servers' => [ 'active_connections', 'connections_failed' ], + 'flexibleServers' => [ 'active_connections', 'connections_failed' ] + }; + + my $metrics_mapping_transformed; + foreach my $metric_type (@{$resource_mapping->{$resource_type}}) { + $metrics_mapping_transformed->{$metric_type} = $self->{metrics_mapping}->{$metric_type}; + } + + foreach my $metric (keys %{$metrics_mapping_transformed}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL connections status. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=connections --custommode=api +--resource= --resource-group= --aggregation='total' +--warning-connections-active='1000' --critical-connections-active='2000' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=connections --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='total' --warning-connections-active='1000' --critical-connections-active='2000' + +Default aggregation: 'total' / 'average', 'minimum' and 'maximum' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-*> B<--critical-*> + +Thresholds where '*' can be: +'connections-active', 'connections-failed', 'connections-aborted', +'connections-total'. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/cpu.pm b/src/cloud/azure/database/postgres/mode/cpu.pm new file mode 100644 index 000000000..8f379e453 --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/cpu.pm @@ -0,0 +1,154 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::cpu; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'cpu_percent' => { + 'output' => 'CPU percent', + 'label' => 'cpu-usage', + 'nlabel' => 'azpostgresql.cpu.utilization.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '100' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL CPU usage. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=cpu --custommode=api +--resource= --resource-group= --aggregation='average' +--warning-cpu-usage='80' --critical-cpu-usage='90' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=cpu --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='average' --warning-cpu-usage='80' --critical-cpu-usage='90' + +Default aggregation: 'average' / 'total', 'minimum' and 'maximum' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-cpu-usage> + +Set warning threshold for CPU utilization percentage. + +=item B<--critical-cpu-usage> + +Set critical threshold for CPU utilization percentage. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/discovery.pm b/src/cloud/azure/database/postgres/mode/discovery.pm new file mode 100644 index 000000000..12848fab7 --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/discovery.pm @@ -0,0 +1,145 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'namespace:s' => { name => 'namespace' }, + 'type:s' => { name => 'type' }, + 'resource-group:s' => { name => 'resource_group' }, + 'location:s' => { name => 'location' }, + 'prettify' => { name => 'prettify' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{namespace} = $self->{option_results}->{namespace}; + $self->{type} = $self->{option_results}->{type}; + $self->{location} = $self->{option_results}->{location}; + $self->{resource_group} = $self->{option_results}->{resource_group}; +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $resources = $options{custom}->azure_list_resources( + namespace => $self->{namespace}, + resource_type => $self->{type}, + location => $self->{location}, + resource_group => $self->{resource_group} + ); + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + + foreach my $resource (@{$resources}) { + next if ($resource->{type} !~ /Microsoft\.DBforPostgreSQL/); + $resource->{type} =~ s/Microsoft\.DBforPostgreSQL\///; + my $resource_group = ''; + $resource_group = $resource->{resourceGroup} if (defined($resource->{resourceGroup})); + $resource_group = $1 if ($resource_group eq '' && defined($resource->{id}) && $resource->{id} =~ /resourceGroups\/(.*)\/providers/); + $resource->{resourceGroup} = $resource_group; + + foreach my $entry (keys %{$resource}) { + next if (ref($resource->{$entry}) ne "HASH"); + my @array; + foreach my $key (keys %{$resource->{$entry}}) { + push @array, { key => $key, value => $resource->{$entry}->{$key} }; + } + $resource->{$entry} = \@array; + } + + push @disco_data, $resource; + } + + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=item B<--namespace> + +Specify resources namespace. + +=item B<--type> + +Specify resources type. + +=item B<--resource-group> + +Specify resources resource group. + +=item B<--location> + +Specify resources location. + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/ioconsumption.pm b/src/cloud/azure/database/postgres/mode/ioconsumption.pm new file mode 100644 index 000000000..3da78aa75 --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/ioconsumption.pm @@ -0,0 +1,154 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::ioconsumption; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'disk_iops_consumed_percentage' => { + 'output' => 'IO Percent', + 'label' => 'ioconsumption-usage', + 'nlabel' => 'azpostgres.ioconsumption.usage.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '100' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Maximum']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL IO comsuption usage. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=io-consumption --custommode=api +--resource= --resource-group= --aggregation='maximum' +--warning-ioconsumption-usage='80' --critical-ioconsumption-usage='90' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=io-consumption --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='maximum' --warning-ioconsumption-usage='80' --critical-ioconsumption-usage='90' + +Default aggregation: 'average' / 'total', 'minimum' and 'maximum' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-ioconsumption-usage> + +Set warning threshold for IO comsuption usage. + +=item B<--critical-ioconsumption-usage> + +Set critical threshold for IO comsuption usage. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/memory.pm b/src/cloud/azure/database/postgres/mode/memory.pm new file mode 100644 index 000000000..ce643bac5 --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/memory.pm @@ -0,0 +1,154 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::memory; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'memory_percent' => { + 'output' => 'Memory percent', + 'label' => 'memory-usage', + 'nlabel' => 'azpostgres.memory.usage.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '100' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL memory usage. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=memory --custommode=api +--resource= --resource-group= --aggregation='average' +--warning-memory-usage='80' --critical-memory-usage='90' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=memory --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='average' --warning-memory-usage='80' --critical-memory-usage='90' + +Default aggregation: 'average' / 'total', 'minimum' and 'maximum' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-memory-usage> + +Set warning threshold for memory utilization percentage. + +=item B<--critical-memory-usage> + +Set critical threshold for memory utilization percentage. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/replication.pm b/src/cloud/azure/database/postgres/mode/replication.pm new file mode 100644 index 000000000..957deda82 --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/replication.pm @@ -0,0 +1,160 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::replication; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'physical_replication_delay_in_seconds' => { + 'output' => 'Replication Lag In Seconds', + 'label' => 'replication-lag', + 'nlabel' => 'azpostgres.replication.lag.seconds', + 'unit' => 's', + 'min' => '0' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Maximum']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + my $resource_mapping = { + 'servers' => [ 'physical_replication_delay_in_seconds' ], + 'flexibleServers' => [ 'physical_replication_delay_in_seconds' ] + }; + + my $metrics_mapping_transformed; + foreach my $metric_type (@{$resource_mapping->{$resource_type}}) { + $metrics_mapping_transformed->{$metric_type} = $self->{metrics_mapping}->{$metric_type}; + } + + foreach my $metric (keys %{$metrics_mapping_transformed}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL replication status. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=connections --custommode=api +--resource= --resource-group= --aggregation='maximum' +--warning-replication-lag='1000' --critical-replication-lag='2000' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=connections --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='maximum' --warning-replication-lag='1000' --critical-replication-lag='2000' + +Default aggregation: 'maximum' / 'average', 'minimum' and 'total' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-*> B<--critical-*> + +Thresholds where '*' can be: +'replication-lag'. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/storage.pm b/src/cloud/azure/database/postgres/mode/storage.pm new file mode 100644 index 000000000..b4668967b --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/storage.pm @@ -0,0 +1,181 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::storage; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'backup_storage_used' => { + 'output' => 'Backup Storage used', + 'label' => 'storage-backup', + 'nlabel' => 'azpostgres.storage.backup.usage.bytes', + 'unit' => 'B', + 'min' => '0' + }, + 'txlogs_storage_used' => { + 'output' => 'Server Log storage used', + 'label' => 'serverlog-usage', + 'nlabel' => 'azpostgres.storage.serverlog.usage.bytes', + 'unit' => 'B', + 'min' => '0' + }, + 'storage_percent' => { + 'output' => 'Storage Percent', + 'label' => 'storage-percent', + 'nlabel' => 'azpostgres.storage.usage.percentage', + 'unit' => '%', + 'min' => '0' + }, + 'storage_used' => { + 'output' => 'Storage Used', + 'label' => 'storage-used', + 'nlabel' => 'azpostgres.storage.usage.bytes', + 'unit' => 'B', + 'min' => '0' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT15M'; + $self->{az_aggregations} = ['Maximum']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + my $resource_mapping = { + 'servers' => [ 'backup_storage_used', 'txlogs_storage_used', 'storage_percent', 'storage_used' ], + 'flexibleServers' => [ 'backup_storage_used', 'txlogs_storage_used', 'storage_percent', 'storage_used' ] + }; + + my $metrics_mapping_transformed; + foreach my $metric_type (@{$resource_mapping->{$resource_type}}) { + $metrics_mapping_transformed->{$metric_type} = $self->{metrics_mapping}->{$metric_type}; + } + + foreach my $metric (keys %{$metrics_mapping_transformed}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL storage usage. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=storage --custommode=api +--resource= --resource-group= --aggregation='maximum' +--warning-storage-used='1000' --critical-storage-used='2000' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=storage --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='maximum' --warning-storage-used='1000' --critical-storage-used='2000' + +Default aggregation: 'maximum' / 'average', 'minimum' and 'total' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-*> B<--critical-*> + +Thresholds where '*' can be: +'storage-backup', 'serverlog-usage', 'storage-percent', 'storage-used'. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/mode/traffic.pm b/src/cloud/azure/database/postgres/mode/traffic.pm new file mode 100644 index 000000000..e99a9212d --- /dev/null +++ b/src/cloud/azure/database/postgres/mode/traffic.pm @@ -0,0 +1,156 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::mode::traffic; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'network_bytes_egress' => { + 'output' => 'Network Out', + 'label' => 'traffic-out', + 'nlabel' => 'azpostgres.traffic.out.bytes', + 'unit' => 'B', + 'min' => '0' + }, + 'network_bytes_ingress' => { + 'output' => 'Network In', + 'label' => 'traffic-in', + 'nlabel' => 'azpostgres.traffic.in.bytes', + 'unit' => 'B', + 'min' => '0' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'resource-type:s' => { name => 'resource_type' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --resource-type option'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.DBforPostgreSQL\/(.*)\/(.*)$/) { + $resource_group = $1; + $resource_type = $2; + $resource = $3; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = $resource_type; + $self->{az_resource_namespace} = 'Microsoft.DBforPostgreSQL'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Database for PostgreSQL network usage. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=traffic --custommode=api +--resource= --resource-group= --aggregation='average' +--warning-traffic-out='80' --critical-traffic-out='90' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::postgres::plugin --mode=traffic --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/servers/' +--aggregation='average' --warning-traffic-out='80' --critical-traffic-out='90' + +Default aggregation: 'average' / 'total', 'minimum' and 'maximum' are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Default: 'servers'). Can be 'servers', 'flexibleServers'. + +=item B<--warning-*> B<--critical-*> + +Thresholds where '*' can be: 'traffic-out', 'traffic-in'. + +=back + +=cut diff --git a/src/cloud/azure/database/postgres/plugin.pm b/src/cloud/azure/database/postgres/plugin.pm new file mode 100644 index 000000000..c98f0a2f2 --- /dev/null +++ b/src/cloud/azure/database/postgres/plugin.pm @@ -0,0 +1,66 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::postgres::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{modes} = { + 'connections' => 'cloud::azure::database::postgres::mode::connections', + 'cpu' => 'cloud::azure::database::postgres::mode::cpu', + 'discovery' => 'cloud::azure::database::postgres::mode::discovery', + 'io-consumption' => 'cloud::azure::database::postgres::mode::ioconsumption', + 'memory' => 'cloud::azure::database::postgres::mode::memory', + 'replication' => 'cloud::azure::database::postgres::mode::replication', + 'storage' => 'cloud::azure::database::postgres::mode::storage', + 'traffic' => 'cloud::azure::database::postgres::mode::traffic' + }; + + $self->{custom_modes}->{azcli} = 'cloud::azure::custom::azcli'; + $self->{custom_modes}->{api} = 'cloud::azure::custom::api'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->{options}->add_options(arguments => { + 'api-version:s' => { name => 'api_version', default => '2018-01-01' } + }); + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure Database for PostgreSQL resources. + +=cut From ef3ff929d0240a08032cde5c7b05cc8b4b90cb38 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 19 Apr 2023 15:25:55 +0200 Subject: [PATCH 394/447] (plugin) network::sonus::sbc::snmp - refactoring + metric v2 (#4370) --- src/network/sonus/sbc/snmp/mode/callstats.pm | 137 +++---- src/network/sonus/sbc/snmp/mode/channels.pm | 366 ++++++++++-------- .../sonus/sbc/snmp/mode/cpudetailed.pm | 59 +++ src/network/sonus/sbc/snmp/mode/dspstats.pm | 152 +++----- src/network/sonus/sbc/snmp/mode/interfaces.pm | 182 +++++++++ src/network/sonus/sbc/snmp/mode/load.pm | 60 +++ src/network/sonus/sbc/snmp/mode/memory.pm | 67 ++++ src/network/sonus/sbc/snmp/mode/storage.pm | 132 +++++++ src/network/sonus/sbc/snmp/mode/swap.pm | 57 +++ src/network/sonus/sbc/snmp/plugin.pm | 17 +- 10 files changed, 891 insertions(+), 338 deletions(-) create mode 100644 src/network/sonus/sbc/snmp/mode/cpudetailed.pm create mode 100644 src/network/sonus/sbc/snmp/mode/interfaces.pm create mode 100644 src/network/sonus/sbc/snmp/mode/load.pm create mode 100644 src/network/sonus/sbc/snmp/mode/memory.pm create mode 100644 src/network/sonus/sbc/snmp/mode/storage.pm create mode 100644 src/network/sonus/sbc/snmp/mode/swap.pm diff --git a/src/network/sonus/sbc/snmp/mode/callstats.pm b/src/network/sonus/sbc/snmp/mode/callstats.pm index d93f5e22c..40de0d3ba 100644 --- a/src/network/sonus/sbc/snmp/mode/callstats.pm +++ b/src/network/sonus/sbc/snmp/mode/callstats.pm @@ -26,84 +26,77 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); +sub prefix_port_output { + my ($self, %options) = @_; + + return "Port '" . $options{instance_value}->{display} . "' number of calls "; +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'port', type => 1, cb_prefix_output => 'prefix_port_output', message_multiple => 'All calls stats on ports are OK' }, + { name => 'port', type => 1, cb_prefix_output => 'prefix_port_output', message_multiple => 'All ports call statistics are ok' } ]; $self->{maps_counters}->{port} = [ - { label => 'current-calls', set => { + { label => 'current', nlabel => 'port.calls.current.count', set => { key_values => [ { name => 'current' }, { name => 'display' } ], - output_template => 'Current calls : %s', + output_template => 'current: %s', perfdatas => [ - { label => 'current', template => '%d', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'total-per-sec', set => { - key_values => [ { name => 'total', per_second => 1 }, { name => 'display' } ], - output_template => 'total calls: %.2f/s', + { label => 'total', nlabel => 'port.calls.total.count', set => { + key_values => [ { name => 'total', diff => 1 }, { name => 'display' } ], + output_template => 'total: %s', perfdatas => [ - { label => 'total', template => '%.2f', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'connected-per-sec', set => { - key_values => [ { name => 'connected', per_second => 1 }, { name => 'display' } ], - output_template => 'connected calls: %.2f/s', + { label => 'connected', nlabel => 'port.calls.connected.count', set => { + key_values => [ { name => 'connected', diff => 1 }, { name => 'display' } ], + output_template => 'connected: %s', perfdatas => [ - { label => 'connected', template => '%.2f', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'refused-per-sec', set => { - key_values => [ { name => 'refused', per_second => 1 }, { name => 'display' } ], - output_template => 'refused calls: %.2f/s', + { label => 'refused', nlabel => 'port.calls.refused.count', set => { + key_values => [ { name => 'refused', diff => 1 }, { name => 'display' } ], + output_template => 'refused: %s', perfdatas => [ - { label => 'refused', template => '%.2f', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'errored-per-sec', set => { - key_values => [ { name => 'errored', per_second => 1 }, { name => 'display' } ], - output_template => 'errored calls: %.2f/s', + { label => 'errored', nlabel => 'port.calls.errored.count', set => { + key_values => [ { name => 'errored', diff => 1 }, { name => 'display' } ], + output_template => 'errored: %s', perfdatas => [ - { label => 'errored', template => '%.2f', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } }, - { label => 'blocked-per-sec', set => { - key_values => [ { name => 'blocked', per_second => 1 }, { name => 'display' } ], - output_template => 'blocked calls: %.2f/s', + { label => 'blocked', nlabel => 'port.calls.blocked.count', set => { + key_values => [ { name => 'blocked', diff => 1 }, { name => 'display' } ], + output_template => 'blocked: %s', perfdatas => [ - { label => 'blocked', template => '%.2f', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } - }, + } ]; } -sub prefix_dsp_output { - my ($self, %options) = @_; - - return "Port => '" . $options{instance_value}->{display} . "' "; -} - sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); bless $self, $class; - $options{options}->add_options(arguments => { - }); + $options{options}->add_options(arguments => {}); return $self; } @@ -114,34 +107,36 @@ my $mapping = { uxPTConnectedCalls => { oid => '.1.3.6.1.4.1.177.15.1.5.1.2.1.7' }, uxPTRefusedCalls => { oid => '.1.3.6.1.4.1.177.15.1.5.1.2.1.8' }, uxPTErroredCalls => { oid => '.1.3.6.1.4.1.177.15.1.5.1.2.1.9' }, - uxPTBlockedCalls => { oid => '.1.3.6.1.4.1.177.15.1.5.1.2.1.18' }, + uxPTBlockedCalls => { oid => '.1.3.6.1.4.1.177.15.1.5.1.2.1.18' } }; - my $oid_uxPortTable = '.1.3.6.1.4.1.177.15.1.5.1.2.1'; sub manage_selection { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_uxPortTable, + nothing_quit => 1 + ); + + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{uxPTCurrentCalls}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{port}->{$instance} = { + current => $result->{uxPTCurrentCalls}, + total => $result->{uxPTTotalCalls}, + connected => $result->{uxPTConnectedCalls}, + refused => $result->{uxPTRefusedCalls}, + errored => $result->{uxPTErroredCalls}, + blocked => $result->{uxPTBlockedCalls}, + display => $instance + }; + } + $self->{cache_name} = "sonus_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - $self->{results} = $options{snmp}->get_table(oid => $oid_uxPortTable, - nothing_quit => 1); - - foreach my $oid (keys %{$self->{results}}) { - next if $oid !~ /^$mapping->{uxPTCurrentCalls}->{oid}\.(.*)$/; - my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); - - $self->{port}->{$instance} = { current => $result->{uxPTCurrentCalls}, - total => $result->{uxPTTotalCalls}, - connected => $result->{uxPTConnectedCalls}, - refused => $result->{uxPTRefusedCalls}, - errored => $result->{uxPTErroredCalls}, - blocked => $result->{uxPTBlockedCalls}, - display => $instance }; - } } 1; @@ -150,17 +145,13 @@ __END__ =head1 MODE -Check Call statistics +Check port call statistics. =over 8 -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Warning on counters. Can be ('current-calls', 'total-per-sec', 'connected-per-sec', 'refused-per-sec', 'errored-per-sec', 'blocked-per-sec') - -=item B<--critical-*> - -Critical on counters. Can be ('current-calls', 'total-per-sec', 'connected-per-sec', 'refused-per-sec', 'errored-per-sec', 'blocked-per-sec') +Thresholds. Can be: 'current', 'total', 'connected', 'refused', 'errored', 'blocked'. =back diff --git a/src/network/sonus/sbc/snmp/mode/channels.pm b/src/network/sonus/sbc/snmp/mode/channels.pm index 03ceb186e..7ea06b92c 100644 --- a/src/network/sonus/sbc/snmp/mode/channels.pm +++ b/src/network/sonus/sbc/snmp/mode/channels.pm @@ -24,253 +24,250 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_status_output { my ($self, %options) = @_; + my $msg; - if ($self->{result_values}->{admstatus} eq 'disabled') { - $msg = ' is disabled (admin)'; + $msg = 'is disabled (admin)'; } else { - $msg = 'Oper Status : ' . $self->{result_values}->{opstatus}; + $msg = 'oper status: ' . $self->{result_values}->{opstatus}; } return $msg; } -sub custom_status_calc { +sub prefix_channel_output { my ($self, %options) = @_; - - $self->{result_values}->{opstatus} = $options{new_datas}->{$self->{instance} . '_opstatus'}; - $self->{result_values}->{admstatus} = $options{new_datas}->{$self->{instance} . '_admstatus'}; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - return 0; + + return sprintf( + "channel '%s/%s/%s/%s' ", + $options{instance_value}->{shelf}, + $options{instance_value}->{slot}, + $options{instance_value}->{port}, + $options{instance_value}->{channel} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'number of channels '; } sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0 }, - { name => 'channels', type => 1, cb_prefix_output => 'prefix_channels_output', message_multiple => 'All channels are ok' } + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'channels', type => 1, cb_prefix_output => 'prefix_channel_output', message_multiple => 'All channels are ok' } ]; + $self->{maps_counters}->{global} = [ - { label => 'total', set => { + { label => 'channels-total', nlabel => 'channels.total.count', display_ok => 0, set => { key_values => [ { name => 'total' } ], - output_template => 'Total channels : %s', + output_template => 'total: %s', perfdatas => [ - { label => 'total', value => 'total', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-outofservice', set => { + { label => 'channels-outofservice', nlabel => 'channels.outofservice.count', display_ok => 0, set => { key_values => [ { name => 'outofservice' } ], - output_template => 'OutOfService : %s', + output_template => 'out of service: %s', perfdatas => [ - { label => 'total_outofservice', value => 'outofservice', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-idle', set => { + { label => 'channels-idle', nlabel => 'channels.idle.count', display_ok => 0, set => { key_values => [ { name => 'idle' } ], - output_template => 'Idle : %s', + output_template => 'idle: %s', perfdatas => [ - { label => 'total_idle', value => 'idle', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-pending', set => { + { label => 'channels-pending', nlabel => 'channels.pending.count', display_ok => 0, set => { key_values => [ { name => 'pending' } ], - output_template => 'Pending : %s', + output_template => 'pending: %s', perfdatas => [ - { label => 'total_pending', value => 'pending', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-waitingforroute', set => { + { label => 'channels-waitingforroute', nlabel => 'channels.waiting_for_route.count', display_ok => 0, set => { key_values => [ { name => 'waitingforroute' } ], - output_template => 'WaitingForRoute : %s', + output_template => 'waiting for route: %s', perfdatas => [ - { label => 'total_waitingforroute', value => 'waitingforroute', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-actionlist', set => { + { label => 'channels-actionlist', nlabel => 'channels.action_list.count', display_ok => 0, set => { key_values => [ { name => 'actionlist' } ], - output_template => 'ActionList : %s', + output_template => 'action list: %s', perfdatas => [ - { label => 'total_actionlist', value => 'actionlist', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-waitingfordigits', set => { + { label => 'channels-waitingfordigits', nlabel => 'channels.waiting_for_digits.count', display_ok => 0, set => { key_values => [ { name => 'waitingfordigits' } ], - output_template => 'WaitingForDigits : %s', + output_template => 'waiting for digits: %s', perfdatas => [ - { label => 'total_waitingfordigits', value => 'waitingfordigits', template => '%s', - min => 0 }, - ], + { template => '%s', + min => 0 } + ] } }, - { label => 'total-remotesetup', set => { + { label => 'channels-remotesetup', nlabel => 'channels.remote_setup.count', display_ok => 0, set => { key_values => [ { name => 'remotesetup' } ], - output_template => 'RemoteSetup : %s', + output_template => 'remote setup: %s', perfdatas => [ - { label => 'total_remotesetup', value => 'remotesetup', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-peersetup', set => { + { label => 'channels-peersetup', nlabel => 'channels.peer_setup.count', display_ok => 0, set => { key_values => [ { name => 'peersetup' } ], - output_template => 'PeerSetup : %s', + output_template => 'peer setup: %s', perfdatas => [ - { label => 'total_peersetup', value => 'peersetup', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-alerting', set => { + { label => 'channels-alerting', nlabel => 'channels.alerting.count', display_ok => 0, set => { key_values => [ { name => 'alerting' } ], - output_template => 'Alerting : %s', + output_template => 'alerting: %s', perfdatas => [ - { label => 'total_alerting', value => 'alerting', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-inbandinfo', set => { + { label => 'channels-inbandinfo', nlabel => 'channels.inband_info.count', display_ok => 0, set => { key_values => [ { name => 'inbandinfo' } ], - output_template => 'InBandInfo : %s', + output_template => 'inband info: %s', perfdatas => [ - { label => 'total_inbandinfo', value => 'inbandinfo', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-connected', set => { + { label => 'channels-connected', nlabel => 'channels.connected.count', display_ok => 0, set => { key_values => [ { name => 'connected' } ], - output_template => 'Connected : %s', + output_template => 'connected: %s', perfdatas => [ - { label => 'total_connected', value => 'connected', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-tonegeneration', set => { + { label => 'channels-tonegeneration', nlabel => 'channels.tone_generation.count', display_ok => 0, set => { key_values => [ { name => 'tonegeneration' } ], - output_template => 'ToneGeneration : %s', + output_template => 'tone generation: %s', perfdatas => [ - { label => 'total_tonegeneration', value => 'tonegeneration', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-releasing', set => { + { label => 'channels-releasing', nlabel => 'channels.releasing.count', display_ok => 0, set => { key_values => [ { name => 'releasing' } ], - output_template => 'Releasing : %s', + output_template => 'releasing: %s', perfdatas => [ - { label => 'total_releasing', value => 'releasing', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-aborting', set => { + { label => 'channels-aborting', nlabel => 'channels.aborting.count', display_ok => 0, set => { key_values => [ { name => 'aborting' } ], - output_template => 'Aborting : %s', + output_template => 'aborting: %s', perfdatas => [ - { label => 'total_aborting', value => 'aborting', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-resetting', set => { + { label => 'channels-resetting', nlabel => 'channels.resetting.count', display_ok => 0, set => { key_values => [ { name => 'resetting' } ], - output_template => 'Resetting : %s', + output_template => 'resetting: %s', perfdatas => [ - { label => 'total_resetting', value => 'resetting', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-up', set => { + { label => 'channels-up', nlabel => 'channels.up.count', display_ok => 0, set => { key_values => [ { name => 'up' } ], - output_template => 'Up : %s', + output_template => 'up: %s', perfdatas => [ - { label => 'total_up', value => 'up', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } }, - { label => 'total-down', set => { + { label => 'channels-down', nlabel => 'channels.down.count', display_ok => 0, set => { key_values => [ { name => 'down' } ], - output_template => 'Down : %s', + output_template => 'down: %s', perfdatas => [ - { label => 'total_down', value => 'down', template => '%s', - min => 0 }, - ], + { template => '%s', min => 0 } + ] } - }, + } ]; - + $self->{maps_counters}->{channels} = [ - { label => 'status', threshold => 0, set => { - key_values => [ { name => 'opstatus' }, { name => 'admstatus' }, { name => 'display' } ], - closure_custom_calc => $self->can('custom_status_calc'), + { label => 'status', type => 2, critical_default => '%{admstatus} eq "enable" and %{opstatus} !~ /up|idle|connected/', set => { + key_values => [ + { name => 'opstatus' }, { name => 'admstatus' }, + { name => 'shelf' }, { name => 'slot' }, { name => 'port' }, { name => 'channel' } + ], closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold_ng } }, - { label => 'seconds', set => { - key_values => [ { name => 'seconds' }, { name => 'display' } ], - output_template => 'lifetime : %s seconds', - perfdatas => [ - { label => 'seconds', value => 'seconds', template => '%s', - min => 0, unit => 's', label_extra_instance => 1, instance_use => 'display' }, - ], + { label => 'channel-lifetime', nlabel => 'channel.lifetime.seconds', set => { + key_values => [ { name => 'seconds' }, { name => 'shelf' }, { name => 'slot' }, { name => 'port' }, { name => 'channel' } ], + output_template => 'lifetime: %s seconds', + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => 's', + instances => [ + 'shelf' . $self->{result_values}->{shelf}, + 'slot' . $self->{result_values}->{slot}, + 'port' . $self->{result_values}->{port}, + 'channel' . $self->{result_values}->{channel}, + ], + value => $self->{result_values}->{seconds}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); + } } - }, + } ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => - { - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{admstatus} eq "enable" and %{opstatus} !~ /up|idle|connected/' }, - }); + + $options{options}->add_options(arguments => { + 'filter-shelf-id:s' => { name => 'filter_shelf_id' }, + 'filter-slot-id:s' => { name => 'filter_slot_id' }, + 'filter-port-id:s' => { name => 'filter_port_id' }, + 'filter-channel-id:s' => { name => 'filter_channel_id' } + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $self->change_macros(macros => ['warning_status', 'critical_status']); -} - -sub prefix_channels_output { - my ($self, %options) = @_; - - return "Channels '" . $options{instance_value}->{display} . "' "; -} - my %map_admin_status = ( 0 => 'down', - 1 => 'up', + 1 => 'up' ); my %map_operation_status = ( 0 => 'outOfService', @@ -289,45 +286,63 @@ my %map_operation_status = ( 13 => 'aborting', 14 => 'resetting', 15 => 'up', - 16 => 'down', + 16 => 'down' ); my $mapping = { - uxChAdminState => { oid => '.1.3.6.1.4.1.177.15.1.5.6.1.5', map => \%map_admin_status }, - uxChOperState => { oid => '.1.3.6.1.4.1.177.15.1.5.6.1.6', map => \%map_operation_status }, - uxChInUseSeconds => { oid => '.1.3.6.1.4.1.177.15.1.5.6.1.7' }, + uxChAdminState => { oid => '.1.3.6.1.4.1.177.15.1.5.6.1.5', map => \%map_admin_status }, + uxChOperState => { oid => '.1.3.6.1.4.1.177.15.1.5.6.1.6', map => \%map_operation_status }, + uxChInUseSeconds => { oid => '.1.3.6.1.4.1.177.15.1.5.6.1.7' } }; - my $oid_uxChannelStatusEntry = '.1.3.6.1.4.1.177.15.1.5.6.1'; sub manage_selection { my ($self, %options) = @_; + $self->{global} = { + total => 0, outofservice => 0, idle => 0, + pending => 0, waitingforroute => 0, actionlist => 0, + waitingfordigits => 0, remotesetup => 0, peersetup => 0, + alerting => 0, inbandinfo => 0, connected => 0, tonegeneration => 0, + releasing => 0, aborting => 0, resetting => 0, up => 0, down => 0 + }; + + my $snmp_result = $options{snmp}->get_table( + oid => $oid_uxChannelStatusEntry, + nothing_quit => 1 + ); + $self->{channels} = {}; - $self->{global} = { total => 0, outofservice => 0, idle => 0, - pending => 0, waitingforroute => 0, actionlist => 0, - waitingfordigits => 0, remotesetup => 0, peersetup => 0, - alerting => 0, inbandinfo => 0, connected => 0, tonegeneration => 0, - releasing => 0, aborting => 0, resetting => 0, up => 0, down => 0 }; + foreach my $oid (keys %$snmp_result) { + next if($oid !~ /^$mapping->{uxChOperState}->{oid}\.(\d+)\.(\d+)\.(\d+)\.(\d+)$/); + my ($shelf, $slot, $port, $channel) = ($1, $2, $3, $4); - $self->{results} = $options{snmp}->get_table(oid => $oid_uxChannelStatusEntry, - nothing_quit => 1); + next if (defined($self->{option_results}->{filter_shelf_id}) && $self->{option_results}->{filter_shelf_id} ne '' && + $shelf !~ /$self->{option_results}->{filter_shelf_id}/); + next if (defined($self->{option_results}->{filter_slot_id}) && $self->{option_results}->{filter_slot_id} ne '' && + $slot !~ /$self->{option_results}->{filter_slot_id}/); + next if (defined($self->{option_results}->{filter_port_id}) && $self->{option_results}->{filter_port_id} ne '' && + $port !~ /$self->{option_results}->{filter_port_id}/); + next if (defined($self->{option_results}->{filter_channel_id}) && $self->{option_results}->{filter_channel_id} ne '' && + $channel !~ /$self->{option_results}->{filter_channel_id}/); - foreach my $oid (keys %{$self->{results}}) { - next if($oid !~ /^$mapping->{uxChOperState}->{oid}\.(.*)$/); - my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + my $instance = $shelf . '.' . $slot . '.' . $port . '.' . $channel; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); $self->{global}->{total}++; my $oper_state = lc($result->{uxChOperState}); $self->{global}->{$oper_state}++; - $self->{channels}->{$instance} = {display => $instance, - opstatus => $result->{uxChOperState}, - admstatus => $result->{uxChAdminState}, - seconds => $result->{uxChInUseSeconds}}; + $self->{channels}->{$instance} = { + shelf => $shelf, + slot => $slot, + port => $port, + channel => $channel, + opstatus => $result->{uxChOperState}, + admstatus => $result->{uxChAdminState}, + seconds => $result->{uxChInUseSeconds} + }; } - } 1; @@ -336,13 +351,29 @@ __END__ =head1 MODE -Check Channels on Sonus +Check channels. =over 8 =item B<--filter-counters> -Only display some counters (Can be 'channels' or 'global'). +Only display some counters. + +=item B<--filter-shelf-id> + +Filter channels by shelf id (can be a regexp). + +=item B<--filter-slot-id> + +Filter channels by slot id (can be a regexp). + +=item B<--filter-port-id> + +Filter channels by port id (can be a regexp). + +=item B<--filter-channel-id> + +Filter channels by channel id (can be a regexp). =item B<--warning-status> @@ -354,15 +385,14 @@ Can used special variables like: %{admstatus}, %{opstatus}, %{display} Set critical threshold for status. Can used special variables like: %{admstatus}, %{opstatus}, %{display} -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Threshold warning. -Can be: 'total', 'total-outofservice', 'total-disassociating', 'total-idle', 'total-pending', 'total-waitingforroute', 'total-actionlist', 'total-waitingfordigits', 'total-remotesetup', 'total-peersetup', 'total-alerting', 'total-inbandinfo', 'total-connected', 'total-tonegeneration', 'total-releasing', 'total-aborting', 'total-resetting', 'total-up', 'total-down', 'seconds' - -=item B<--critical-*> - -Threshold critical. -Can be: 'total', 'total', 'total-outofservice', 'total-disassociating', 'total-idle', 'total-pending', 'total-waitingforroute', 'total-actionlist', 'total-waitingfordigits', 'total-remotesetup', 'total-peersetup', 'total-alerting', 'total-inbandinfo', 'total-connected', 'total-tonegeneration', 'total-releasing', 'total-aborting', 'total-resetting', 'total-up', 'total-down', 'seconds' +Thresholds. +Can be: 'channels-total', 'channels-outofservice', 'channels-idle', 'channels-pending', +'channels-waitingforroute', 'channels-actionlist', 'channels-waitingfordigits', +'channels-remotesetup', 'channels-peersetup', 'channels-alerting', +'channels-inbandinfo', 'channels-connected', 'channels-tonegeneration', 'channels-releasing', +'channels-aborting', 'channels-resetting', 'channels-up', 'channels-down', 'channel-lifetime'. =back diff --git a/src/network/sonus/sbc/snmp/mode/cpudetailed.pm b/src/network/sonus/sbc/snmp/mode/cpudetailed.pm new file mode 100644 index 000000000..359d0d78b --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/cpudetailed.pm @@ -0,0 +1,59 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::cpudetailed; + +use base qw(snmp_standard::mode::cpudetailed); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system CPUs (UCD-SNMP-MIB) (User, Nice, System, Idle, Wait, Kernel, Interrupt, SoftIRQ, Steal, Guest, GuestNice) +An average of all CPUs. + +=over 8 + +=item B<--warning-*> + +Threshold warning in percent. +Can be: 'user', 'nice', 'system', 'idle', 'wait', 'kernel', 'interrupt', 'softirq', 'steal', 'guest', 'guestnice'. + +=item B<--critical-*> + +Threshold critical in percent. +Can be: 'user', 'nice', 'system', 'idle', 'wait', 'kernel', 'interrupt', 'softirq', 'steal', 'guest', 'guestnice'. + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/mode/dspstats.pm b/src/network/sonus/sbc/snmp/mode/dspstats.pm index 0541d273f..b6ce02f4c 100644 --- a/src/network/sonus/sbc/snmp/mode/dspstats.pm +++ b/src/network/sonus/sbc/snmp/mode/dspstats.pm @@ -24,57 +24,12 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_state_output { my ($self, %options) = @_; - my $msg = sprintf("state is '%s'", $self->{result_values}->{state}); - return $msg; -} - -sub custom_state_calc { - my ($self, %options) = @_; - - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - return 0; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'dsp', type => 1, cb_prefix_output => 'prefix_dsp_output', message_multiple => 'All DSP stats and states are OK' }, - ]; - $self->{maps_counters}->{dsp} = [ - { label => 'status', threshold => 0, set => { - key_values => [ { name => 'state' }, { name => 'display' } ], - closure_custom_calc => \&custom_state_calc, - closure_custom_output => \&custom_state_output, - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, - } - }, - { label => 'cpu', set => { - key_values => [ { name => 'cpu' }, { name => 'display' } ], - output_template => 'CPU Usage: %s', - perfdatas => [ - { label => 'cpu', value => 'cpu', template => '%d', - min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, - ], - } - }, - { label => 'channels', set => { - key_values => [ { name => 'channels' }, { name => 'display' } ], - output_template => 'Active Channels: %s', - perfdatas => [ - { label => 'channels', value => 'channels', template => '%d', - min => 0, unit => 'channels', label_extra_instance => 1, instance_use => 'display' }, - ], - } - }, - ]; + return sprintf("state is '%s'", $self->{result_values}->{state}); } sub prefix_dsp_output { @@ -83,59 +38,84 @@ sub prefix_dsp_output { return "DSP '" . $options{instance_value}->{display} . "' "; } -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; +sub set_counters { + my ($self, %options) = @_; - $options{options}->add_options(arguments => - { - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{state} eq "down"' }, - }); - return $self; + $self->{maps_counters_type} = [ + { name => 'dsp', type => 1, cb_prefix_output => 'prefix_dsp_output', message_multiple => 'All DSP stats and states are ok' } + ]; + + $self->{maps_counters}->{dsp} = [ + { label => 'status', type => 2, critical_default => '%{state} eq "down"', set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_output => \&custom_state_output, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'cpu-utilization', nlabel => 'dsp.cpu.utilization.percentage', set => { + key_values => [ { name => 'cpu' }, { name => 'display' } ], + output_template => 'CPU usage: %.2f %%', + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' } + ] + } + }, + { label => 'channels-active', nlabel => 'dsp.channels.active.count', set => { + key_values => [ { name => 'channels' }, { name => 'display' } ], + output_template => 'active channels: %s', + perfdatas => [ + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] + } + } + ]; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; - $self->change_macros(macros => ['warning_status', 'critical_status']); + $options{options}->add_options(arguments => {}); + + return $self; } my %map_status = ( 0 => 'down', - 1 => 'up', + 1 => 'up' ); my $mapping = { - uxDSPIsPresent => { oid => '.1.3.6.1.4.1.177.15.1.6.1.3' }, - uxDSPCPUUsage => { oid => '.1.3.6.1.4.1.177.15.1.6.1.4' }, - uxDSPChannelsInUse => { oid => '.1.3.6.1.4.1.177.15.1.6.1.5' }, - uxDSPServiceStatus => { oid => '.1.3.6.1.4.1.177.15.1.6.1.6', map => \%map_status }, + uxDSPIsPresent => { oid => '.1.3.6.1.4.1.177.15.1.6.1.3' }, + uxDSPCPUUsage => { oid => '.1.3.6.1.4.1.177.15.1.6.1.4' }, + uxDSPChannelsInUse => { oid => '.1.3.6.1.4.1.177.15.1.6.1.5' }, + uxDSPServiceStatus => { oid => '.1.3.6.1.4.1.177.15.1.6.1.6', map => \%map_status } }; - my $oid_uxDSPResourceTable = '.1.3.6.1.4.1.177.15.1.6.1'; sub manage_selection { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_uxDSPResourceTable, + nothing_quit => 1 + ); - $self->{results} = $options{snmp}->get_table(oid => $oid_uxDSPResourceTable, - nothing_quit => 1); - - foreach my $oid (keys %{$self->{results}}) { + foreach my $oid (keys %$snmp_result) { next if($oid !~ /^$mapping->{uxDSPServiceStatus}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); next if ($result->{uxDSPIsPresent} eq '0'); - $self->{dsp}->{$instance} = { state => $result->{uxDSPServiceStatus}, - cpu => $result->{uxDSPCPUUsage}, - channels => $result->{uxDSPChannelsInUse}, - display => $instance }; + $self->{dsp}->{$instance} = { + state => $result->{uxDSPServiceStatus}, + cpu => $result->{uxDSPCPUUsage}, + channels => $result->{uxDSPChannelsInUse}, + display => $instance + }; } } @@ -145,27 +125,23 @@ __END__ =head1 MODE -Check Digital Signal Processing statistics +Check Digital Signal Processing statistics. =over 8 -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Warning on counters. Can be ('cpu', 'channels') - -=item B<--critical-*> - -Warning on counters. Can be ('cpu', 'channels') +Thresholds. Can be: 'cpu-utilization', 'channels-active'. =item B<--warning-status> -Set warning threshold for status. Use "%{state}" as a special variable. -Useful to be notified when tunnel is up "%{state} eq 'up'" +Set warning threshold for status. +Can used special variables like: %{state}, %{display} =item B<--critical-status> -Set critical threshold for status. Use "%{state}" as a special variable. -Useful to be notified when tunnel is up "%{state} eq 'up'" +Set critical threshold for status (Default: '%{state} eq "down"'). +Can used special variables like: %{state}, %{display} =back diff --git a/src/network/sonus/sbc/snmp/mode/interfaces.pm b/src/network/sonus/sbc/snmp/mode/interfaces.pm new file mode 100644 index 000000000..cd3656ac3 --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/interfaces.pm @@ -0,0 +1,182 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--check-metrics> + +If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast', +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', 'bps', 'counter'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--units-cast> + +Units of thresholds for communication types (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--map-speed-dsl> + +Get interface speed configuration for interface type 'adsl' and 'vdsl2'. + +Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name + +E.g: --map-speed-dsl=Et0.835,Et0-vdsl2 + +=item B<--force-counters64> + +Force to use 64 bits counters only. Can be used to improve performance. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/mode/load.pm b/src/network/sonus/sbc/snmp/mode/load.pm new file mode 100644 index 000000000..de3a90ba7 --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/load.pm @@ -0,0 +1,60 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::load; + +use base qw(snmp_standard::mode::loadaverage); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system load-average. + +=over 8 + +=item B<--warning> + +Threshold warning (1min,5min,15min). + +=item B<--critical> + +Threshold critical (1min,5min,15min). + +=item B<--average> + +Load average for the number of CPUs. + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/mode/memory.pm b/src/network/sonus/sbc/snmp/mode/memory.pm new file mode 100644 index 000000000..535b2ebbb --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/memory.pm @@ -0,0 +1,67 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::memory; + +use base qw(snmp_standard::mode::memory); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage (UCD-SNMP-MIB). + +=over 8 + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute') (Deprecated. Please use new counters directly) + +=item B<--free> + +Thresholds are on free space left (Deprecated. Please use new counters directly) + +=item B<--swap> + +Check swap also. + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%), +'swap' (B), 'swap-free' (B), 'swap-prct' (%), +'buffer' (B), 'cached' (B), 'shared' (B). + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/mode/storage.pm b/src/network/sonus/sbc/snmp/mode/storage.pm new file mode 100644 index 000000000..1ddae7dff --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/storage.pm @@ -0,0 +1,132 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::storage; + +use base qw(snmp_standard::mode::storage); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=item B<--warning-access> + +Threshold warning. + +=item B<--critical-access> + +Threshold critical. +Check if storage is readOnly: --critical-access=readOnly + +=item B<--add-access> + +Check storage access (readOnly, readWrite). + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--storage> + +Set the storage (number expected) ex: 1, 2,... (empty means 'check all storage'). + +=item B<--name> + +Allows to use storage name with option --storage instead of storage oid index. + +=item B<--regexp> + +Allows to use regexp to filter storage (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--path-best-match> + +Allows to select best path mount point (with --name). + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter storage (default: hrStorageDescr) (values: hrStorageDescr, hrFSMountPoint). + +=item B<--oid-display> + +Choose OID used to display storage (default: hrStorageDescr) (values: hrStorageDescr, hrFSMountPoint). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=item B<--show-cache> + +Display cache storage datas. + +=item B<--space-reservation> + +Some filesystem has space reserved (like ext4 for root). +The value is in percent of total (Default: none) (results like 'df' command). + +=item B<--filter-duplicate> + +Filter duplicate storages (in used size and total size). + +=item B<--filter-storage-type> + +Filter storage types with a regexp (Default: '^(hrStorageFixedDisk|hrStorageNetworkDisk|hrFSBerkeleyFFS)$'). + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/mode/swap.pm b/src/network/sonus/sbc/snmp/mode/swap.pm new file mode 100644 index 000000000..3b805896b --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/swap.pm @@ -0,0 +1,57 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::swap; + +use base qw(snmp_standard::mode::swap); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check swap memory (UCD-SNMP-MIB). + +=over 8 + +=item B<--no-swap> + +Threshold if no active swap (default: 'critical'). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%). + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/plugin.pm b/src/network/sonus/sbc/snmp/plugin.pm index 8dd0d3a42..1b70e0741 100644 --- a/src/network/sonus/sbc/snmp/plugin.pm +++ b/src/network/sonus/sbc/snmp/plugin.pm @@ -29,20 +29,19 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; - %{$self->{modes}} = ( + $self->{modes} = { 'call-statistics' => 'network::sonus::sbc::snmp::mode::callstats', 'channels' => 'network::sonus::sbc::snmp::mode::channels', 'cpu' => 'snmp_standard::mode::cpu', - 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'cpu-detailed' => 'network::sonus::sbc::snmp::mode::cpudetailed', 'dsp-stats' => 'network::sonus::sbc::snmp::mode::dspstats', - 'interfaces' => 'snmp_standard::mode::interfaces', + 'interfaces' => 'network::sonus::sbc::snmp::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'load' => 'snmp_standard::mode::loadaverage', - 'memory' => 'snmp_standard::mode::memory', - 'storage' => 'snmp_standard::mode::storage', - 'swap' => 'snmp_standard::mode::swap', - ); + 'load' => 'network::sonus::sbc::snmp::mode::load', + 'memory' => 'network::sonus::sbc::snmp::mode::memory', + 'storage' => 'network::sonus::sbc::snmp::mode::storage', + 'swap' => 'network::sonus::sbc::snmp::mode::swap' + }; return $self; } From 3cb38f2046dc519e881405e86d1387cf0c975ca4 Mon Sep 17 00:00:00 2001 From: THEPAUT Date: Thu, 20 Apr 2023 03:41:05 -0400 Subject: [PATCH 395/447] (plugin) notification::email - update (#4372) --- src/notification/email/mode/alert.pm | 39 +++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/notification/email/mode/alert.pm b/src/notification/email/mode/alert.pm index 20bea8f74..b57829a94 100644 --- a/src/notification/email/mode/alert.pm +++ b/src/notification/email/mode/alert.pm @@ -598,7 +598,7 @@ sub service_message { my $line_break = '
                  '; - $self->{option_results}->{service_longoutput} =~ s/\n/
                  /g; + $self->{option_results}->{service_longoutput} =~ s/\\n/
                  /g; $self->{payload_attachment}->{subject} = '*** ' . $self->{option_results}->{type} . ' : ' . $self->{option_results}->{service_description} . ' '. $self->{option_results}->{service_state} . ' on ' . $self->{option_results}->{host_name} . ' ***'; $self->{payload_attachment}->{alt_message} = ' @@ -954,6 +954,22 @@ sub run { ); } + my $html_part = Email::MIME->create( + attributes => { + content_type => 'text/html', + charset => 'UTF-8' + }, + body => $self->{payload_attachment}->{html_message} + ); + + my $text_part = Email::MIME->create( + attributes => { + content_type => 'text/plain', + charset => 'UTF-8' + }, + body => $self->{payload_attachment}->{alt_message} + ); + my $email = Email::MIME->create( header_str => [ From => $self->{option_results}->{from_address}, @@ -962,20 +978,13 @@ sub run { ], parts => [ Email::MIME->create( - attributes => { - content_type => 'text/plain', - charset => 'UTF-8' - }, - body => $self->{payload_attachment}->{alt_message} - ), - Email::MIME->create( - attributes => { - content_type => 'text/html', - charset => 'UTF-8' - }, - body => $self->{payload_attachment}->{html_message} - ), - $attachement + attributes => { + content_type => 'multipart/alternative', + charset => 'UTF-8', + }, + parts => [$text_part, $html_part], + ), + $attachement ] ); From ca24679f88fffd72a8dca776e7d20d415821b732 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Thu, 20 Apr 2023 10:33:37 +0200 Subject: [PATCH 396/447] (plugin) network::sonus::sbc::snmp - mode cpu metric v2 (#4373) --- src/network/sonus/sbc/snmp/mode/cpu.pm | 70 ++++++++++++++++++++++++++ src/network/sonus/sbc/snmp/plugin.pm | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/network/sonus/sbc/snmp/mode/cpu.pm diff --git a/src/network/sonus/sbc/snmp/mode/cpu.pm b/src/network/sonus/sbc/snmp/mode/cpu.pm new file mode 100644 index 000000000..293936166 --- /dev/null +++ b/src/network/sonus/sbc/snmp/mode/cpu.pm @@ -0,0 +1,70 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::sonus::sbc::snmp::mode::cpu; + +use base qw(snmp_standard::mode::cpudetailed); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check system CPUs. +(The average, over the last minute, of the percentage +of time that this processor was not idle) + +=over 8 + +=item B<--use-ucd> + +Use UCD mib for cpu average. + +=item B<--warning-average> + +Warning threshold average CPU utilization. + +=item B<--critical-average> + +Critical threshold average CPU utilization. + +=item B<--warning-core> + +Warning thresholds for each CPU core + +=item B<--critical-core> + +Critical thresholds for each CPU core + +=back + +=cut diff --git a/src/network/sonus/sbc/snmp/plugin.pm b/src/network/sonus/sbc/snmp/plugin.pm index 1b70e0741..0d28cb28e 100644 --- a/src/network/sonus/sbc/snmp/plugin.pm +++ b/src/network/sonus/sbc/snmp/plugin.pm @@ -32,7 +32,7 @@ sub new { $self->{modes} = { 'call-statistics' => 'network::sonus::sbc::snmp::mode::callstats', 'channels' => 'network::sonus::sbc::snmp::mode::channels', - 'cpu' => 'snmp_standard::mode::cpu', + 'cpu' => 'network::sonus::sbc::snmp::mode::cpu', 'cpu-detailed' => 'network::sonus::sbc::snmp::mode::cpudetailed', 'dsp-stats' => 'network::sonus::sbc::snmp::mode::dspstats', 'interfaces' => 'network::sonus::sbc::snmp::mode::interfaces', From 9c9893b4772cdb3e9eaa14f096ce2b40c50a6050 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Thu, 20 Apr 2023 14:03:53 +0200 Subject: [PATCH 397/447] (plugin) cloud::aws::cloudwatch - mode discovery fix packaging dep (#4374) --- packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json b/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json index 3da189d2c..20de8fada 100644 --- a/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json +++ b/packaging/centreon-plugin-Cloud-Aws-Cloudwatch-Api/pkg.json @@ -13,6 +13,7 @@ "cloud/aws/ec2/mode/discovery.pm", "cloud/aws/ec2/mode/discoveryspotfleetrequests.pm", "cloud/aws/efs/mode/discovery.pm", + "cloud/aws/elasticache/mode/discovery.pm", "cloud/aws/elb/application/mode/discovery.pm", "cloud/aws/elb/classic/mode/discovery.pm", "cloud/aws/elb/network/mode/discovery.pm", From c642befb68297d4cd516c9532b9518d2bebd2d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Duret?= Date: Thu, 20 Apr 2023 16:09:30 +0200 Subject: [PATCH 398/447] add header in azure_list_resources_set_url (#4376) --- src/cloud/azure/custom/api.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cloud/azure/custom/api.pm b/src/cloud/azure/custom/api.pm index ab472e781..c40569e82 100644 --- a/src/cloud/azure/custom/api.pm +++ b/src/cloud/azure/custom/api.pm @@ -1227,7 +1227,8 @@ sub azure_list_policystates { full_url => $url, hostname => '', get_params => $get_params, - query_form_post => '' + query_form_post => '', + header => ['Content-Type: application/json'] ); foreach (@{$response->{value}}) { push @$full_response, $_; From d22a8fa3f383ac7507c75d98a737dd3031a479a6 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 21 Apr 2023 17:39:34 +0200 Subject: [PATCH 399/447] (plugin) network::barracuda::bma::snmp - mode mails fix help (#4381) --- src/network/barracuda/bma/snmp/mode/mails.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/barracuda/bma/snmp/mode/mails.pm b/src/network/barracuda/bma/snmp/mode/mails.pm index c0923db6f..7f6299cd1 100644 --- a/src/network/barracuda/bma/snmp/mode/mails.pm +++ b/src/network/barracuda/bma/snmp/mode/mails.pm @@ -135,7 +135,9 @@ Check e-mails. =item B<--warning-*> B<--critical-*> Thresholds. -Can be: 'firmware-space', 'maillog-space'. +Can be: 'internal-hourly', 'internal-daily', 'internal-total', +'outbound-hourly', 'outbound-daily', 'outbound-total', +'inbound-hourly', 'inbound-daily', 'inbound-total'. =back From 4d3c939b4a56120504166a49e284c58150cfa3db Mon Sep 17 00:00:00 2001 From: THEPAUT Date: Mon, 24 Apr 2023 03:54:57 -0400 Subject: [PATCH 400/447] (plugin) notification::email - update (#4372) --- packaging/centreon-plugin-Notification-Email/deb.json | 6 ++++++ packaging/centreon-plugin-Notification-Email/pkg.json | 9 +++++++++ packaging/centreon-plugin-Notification-Email/rpm.json | 7 +++++++ 3 files changed, 22 insertions(+) create mode 100644 packaging/centreon-plugin-Notification-Email/deb.json create mode 100644 packaging/centreon-plugin-Notification-Email/pkg.json create mode 100644 packaging/centreon-plugin-Notification-Email/rpm.json diff --git a/packaging/centreon-plugin-Notification-Email/deb.json b/packaging/centreon-plugin-Notification-Email/deb.json new file mode 100644 index 000000000..15206f567 --- /dev/null +++ b/packaging/centreon-plugin-Notification-Email/deb.json @@ -0,0 +1,6 @@ +{ + "dependencies": [ + "libemail-sender-perl", + "libemail-mime-perl" + ] +} diff --git a/packaging/centreon-plugin-Notification-Email/pkg.json b/packaging/centreon-plugin-Notification-Email/pkg.json new file mode 100644 index 000000000..f743b55ad --- /dev/null +++ b/packaging/centreon-plugin-Notification-Email/pkg.json @@ -0,0 +1,9 @@ +{ + "pkg_name": "centreon-plugin-Notification-Email", + "pkg_summary": "Centreon Plugin to send notifications by Email", + "plugin_name": "centreon_notification_email.pl", + "files": [ + "centreon/plugins/script_simple.pm", + "notification/email" + ] +} diff --git a/packaging/centreon-plugin-Notification-Email/rpm.json b/packaging/centreon-plugin-Notification-Email/rpm.json new file mode 100644 index 000000000..2e53d426a --- /dev/null +++ b/packaging/centreon-plugin-Notification-Email/rpm.json @@ -0,0 +1,7 @@ +{ + "dependencies": [ + "perl(Email::MIME)", + "perl(Email::Simple)", + "perl(Email::Sender)" + ] +} From b1e5cde2b0bd2034757607585bf6a2cdcbe1846b Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 24 Apr 2023 14:04:41 +0200 Subject: [PATCH 401/447] (plugin) cloud::aws::directconnect - new (#4382) --- .../deb.json | 5 + .../pkg.json | 10 + .../rpm.json | 5 + src/cloud/aws/custom/awscli.pm | 62 +++++ src/cloud/aws/custom/mode.pm | 33 ++- src/cloud/aws/custom/paws.pm | 50 ++++ .../aws/directconnect/mode/connections.pm | 249 ++++++++++++++++++ src/cloud/aws/directconnect/mode/discovery.pm | 104 ++++++++ .../aws/directconnect/mode/listconnections.pm | 103 ++++++++ .../mode/listvirtualinterfaces.pm | 114 ++++++++ .../directconnect/mode/virtualinterfaces.pm | 245 +++++++++++++++++ src/cloud/aws/directconnect/plugin.pm | 53 ++++ 12 files changed, 1020 insertions(+), 13 deletions(-) create mode 100644 packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/deb.json create mode 100644 packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/pkg.json create mode 100644 packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/rpm.json create mode 100644 src/cloud/aws/directconnect/mode/connections.pm create mode 100644 src/cloud/aws/directconnect/mode/discovery.pm create mode 100644 src/cloud/aws/directconnect/mode/listconnections.pm create mode 100644 src/cloud/aws/directconnect/mode/listvirtualinterfaces.pm create mode 100644 src/cloud/aws/directconnect/mode/virtualinterfaces.pm create mode 100644 src/cloud/aws/directconnect/plugin.pm diff --git a/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/deb.json b/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/deb.json new file mode 100644 index 000000000..8133a85e5 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libdatetime-perl" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/pkg.json b/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/pkg.json new file mode 100644 index 000000000..4da476c43 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/pkg.json @@ -0,0 +1,10 @@ +{ + "pkg_name": "centreon-plugin-Cloud-Aws-Directconnect-Api", + "pkg_summary": "Centreon Plugin to monitor Amazon AWS Direct Connect service using Cloudwatch API", + "plugin_name": "centreon_aws_directconnect_api.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "cloud/aws/custom/", + "cloud/aws/directconnect/" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/rpm.json b/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/rpm.json new file mode 100644 index 000000000..e9dff7552 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Aws-Directconnect-Api/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(DateTime)" + ] +} diff --git a/src/cloud/aws/custom/awscli.pm b/src/cloud/aws/custom/awscli.pm index 51d7692fe..00559678e 100644 --- a/src/cloud/aws/custom/awscli.pm +++ b/src/cloud/aws/custom/awscli.pm @@ -914,6 +914,68 @@ sub elasticache_describe_cache_clusters { return $results; } +sub directconnect_describe_connections_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "directconnect describe-connections --region $self->{option_results}->{region} --output json"; + $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + $cmd_options .= " --no-verify-ssl 2>/dev/null" if (defined($self->{option_results}->{skip_ssl_check})); + + return $cmd_options; +} + +sub directconnect_describe_connections { + my ($self, %options) = @_; + + my $cmd_options = $self->directconnect_describe_connections_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + my $results = {}; + foreach (@{$raw_results->{connections}}) { + $results->{ $_->{connectionId} } = { + name => $_->{connectionName}, + state => $_->{connectionState}, + bandwidth => $_->{bandwidth} + }; + } + + return $results; +} + +sub directconnect_describe_virtual_interfaces_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "directconnect describe-virtual-interfaces --region $self->{option_results}->{region} --output json"; + $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + $cmd_options .= " --no-verify-ssl 2>/dev/null" if (defined($self->{option_results}->{skip_ssl_check})); + + return $cmd_options; +} + +sub directconnect_describe_virtual_interfaces { + my ($self, %options) = @_; + + my $cmd_options = $self->directconnect_describe_virtual_interfaces_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + my $results = {}; + foreach (@{$raw_results->{virtualInterfaces}}) { + $results->{ $_->{virtualInterfaceId} } = { + name => $_->{virtualInterfaceName}, + state => $_->{virtualInterfaceState}, + type => $_->{virtualInterfaceType}, + vlan => $_->{vlan}, + connectionId => $_->{connectionId} + }; + } + + return $results; +} + 1; __END__ diff --git a/src/cloud/aws/custom/mode.pm b/src/cloud/aws/custom/mode.pm index 14a3e5dd2..bde8085e4 100644 --- a/src/cloud/aws/custom/mode.pm +++ b/src/cloud/aws/custom/mode.pm @@ -71,18 +71,25 @@ sub custom_metric_perfdata { sub custom_metric_output { my ($self, %options) = @_; - my $msg = ''; + my $extra_unit = ''; + my $metric_label = 'value'; if (defined($self->{instance_mode}->{option_results}->{per_sec})) { - my ($value, $unit) = ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'B') ? - $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}) : - ($self->{result_values}->{value_per_sec}, $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit}); - $msg = sprintf("%s: %.2f %s", $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{output}, $value, $unit . '/s'); - } else { - my ($value, $unit) = ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'B') ? - $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}) : - ($self->{result_values}->{value}, $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit}); - $msg = sprintf("%s: %.2f %s", $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{output}, $value, $unit); + $metric_label = 'value_per_sec'; + $extra_unit = '/s'; } + + my ($value, $unit); + if ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'B') { + ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{$metric_label}); + } elsif ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'bps') { + ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{$metric_label}, network => 1); + $extra_unit = '/s'; + } else { + ($value, $unit) = ($self->{result_values}->{$metric_label}, $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit}); + } + + my $msg = sprintf("%s: %.2f %s", $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{output}, $value, $unit . $extra_unit); + return $msg; } @@ -112,16 +119,16 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'metrics', type => 3, cb_prefix_output => 'prefix_metric_output', cb_long_output => 'long_output', - message_multiple => defined($data->{extra_params}->{message_mutiple}) ? $data->{extra_params}->{message_mutiple} : 'All metrics are ok', + message_multiple => defined($data->{extra_params}->{message_multiple}) ? $data->{extra_params}->{message_multiple} : 'All metrics are ok', indent_long_output => ' ', group => [ { name => 'statistics', display_long => 1, cb_prefix_output => 'prefix_statistics_output', - message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } }, + message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } } ] } ]; - foreach my $metric (keys %{$self->{metrics_mapping}}) { + foreach my $metric (sort keys %{$self->{metrics_mapping}}) { my $entry = { label => $self->{metrics_mapping}->{$metric}->{label}, set => { diff --git a/src/cloud/aws/custom/paws.pm b/src/cloud/aws/custom/paws.pm index 579e398a2..2a30b1b12 100644 --- a/src/cloud/aws/custom/paws.pm +++ b/src/cloud/aws/custom/paws.pm @@ -789,6 +789,56 @@ sub elasticache_describe_cache_clusters { return $results; } +sub directconnect_describe_connections { + my ($self, %options) = @_; + + my $results = {}; + eval { + my $ec = $self->{paws}->service('DirectConnect', region => $self->{option_results}->{region}); + my $connections = $ec->DescribeConnections(); + + foreach (@{$connections->{Connections}}) { + $results->{ $_->{ConnectionId} } = { { + name => $_->{ConnectionName}, + state => $_->{ConnectionState}, + bandwidth => $_->{Bandwidth} + }; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $results; +} + +sub directconnect_describe_virtual_interfaces { + my ($self, %options) = @_; + + my $results = {}; + eval { + my $ec = $self->{paws}->service('DirectConnect', region => $self->{option_results}->{region}); + my $vi = $ec->DescribeVirtualInterfaces(); + + foreach (@{$vi->{VirtualInterfaces}}) { + $results->{ $_->{VirtualInterfaceId} } = { + name => $_->{VirtualInterfaceName}, + state => $_->{VirtualInterfaceState}, + type => $_->{VirtualInterfaceType}, + vlan => $_->{Vlan}, + connectionId => $_->{ConnectionId} + }; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $results; +} + 1; __END__ diff --git a/src/cloud/aws/directconnect/mode/connections.pm b/src/cloud/aws/directconnect/mode/connections.pm new file mode 100644 index 000000000..f11d23263 --- /dev/null +++ b/src/cloud/aws/directconnect/mode/connections.pm @@ -0,0 +1,249 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::directconnect::mode::connections; + +use base qw(cloud::aws::custom::mode); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + extra_params => { + message_multiple => 'All connections are ok' + }, + metrics => { + ConnectionBpsEgress => { + output => 'outbound data', + label => 'connection-egress', + nlabel => { + absolute => 'connection.egress.bitspersecond', + }, + unit => 'bps' + }, + ConnectionBpsIngress => { + output => 'inbound data', + label => 'connection-ingress', + nlabel => { + absolute => 'connection.ingress.bitspersecond', + }, + unit => 'bps' + }, + ConnectionPpsEgress => { + output => 'outbound packets data', + label => 'connection-packets-egress', + nlabel => { + absolute => 'connection.egress.packets.persecond', + }, + unit => '/s' + }, + ConnectionPpsIngress => { + output => 'inbound packet data', + label => 'connection-packets-ingress', + nlabel => { + absolute => 'connection.ingress.packets.persecond', + }, + unit => '/s' + }, + ConnectionLightLevelTx => { + output => 'outbound light level', + label => 'connection-ligh-level-outbound', + nlabel => { + absolute => 'connection.outbound.light.level.dbm', + }, + unit => 'dBm' + }, + ConnectionLightLevelRx => { + output => 'inbound light level', + label => 'connection-ligh-level-inbound', + nlabel => { + absolute => 'connection.inbound.light.level.dbm', + }, + unit => 'dBm' + } + } + }; + + return $metrics_mapping; +} + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf('state: %s [bandwidth: %s]', $self->{result_values}->{state}, $self->{result_values}->{bandwidth}); +} + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "connection '" . $options{instance_value}->{display} . "' "; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking connection '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_statistics_output { + my ($self, %options) = @_; + + return "statistic '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->SUPER::set_counters(%options); + + unshift @{$self->{maps_counters_type}->[0]->{group}}, { + name => 'status', + type => 0, skipped_code => { -10 => 1 } + }; + + $self->{maps_counters}->{status} = [ + { label => 'status', type => 2, set => { + key_values => [ { name => 'state' }, { name => 'bandwidth' }, { name => 'connectionName' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-connection-id:s' => { name => 'filter_connection_id' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $connections = $options{custom}->directconnect_describe_connections(); + + foreach my $connection_id (keys %$connections) { + next if (defined($self->{option_results}->{filter_connection_id}) && $self->{option_results}->{filter_connection_id} ne '' + && $connection_id !~ /$self->{option_results}->{filter_connection_id}/); + + $self->{metrics}->{$connection_id} = { + display => $connections->{$connection_id}->{name}, + status => { + connectionName => $connections->{$connection_id}->{name}, + bandwidth => $connections->{$connection_id}->{bandwidth}, + state => $connections->{$connection_id}->{state} + }, + statistics => {} + }; + + my $cw_metrics = $options{custom}->cloudwatch_get_metrics( + namespace => 'AWS/DX', + dimensions => [ { Name => 'ConnectionId', Value => $connection_id } ], + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{aws_timeframe}, + period => $self->{aws_period} + ); + + foreach my $metric (@{$self->{aws_metrics}}) { + foreach my $statistic (@{$self->{aws_statistics}}) { + next if (!defined($cw_metrics->{$metric}->{lc($statistic)}) && + !defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$connection_id}->{display} = $connections->{$connection_id}->{name}; + $self->{metrics}->{$connection_id}->{statistics}->{lc($statistic)}->{display} = $statistic; + $self->{metrics}->{$connection_id}->{statistics}->{lc($statistic)}->{timeframe} = $self->{aws_timeframe}; + $self->{metrics}->{$connection_id}->{statistics}->{lc($statistic)}->{$metric} = + defined($cw_metrics->{$metric}->{lc($statistic)}) ? + $cw_metrics->{$metric}->{lc($statistic)} : 0; + } + } + } + + if (scalar(keys %{$self->{metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No connection found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check direct connect connections. + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::directconnect::plugin --custommode=paws --mode=connections --region='eu-west-1' +--filter-metric='ConnectionBpsEgress' --statistic='average' --critical-connection-egress='10Mb' --verbose + +See 'https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html' for more informations. + +Default statistic: 'average' / All satistics are valid. + +=over 8 + +=item B<--filter-connection-id> + +Filter connection id (can be a regexp). + +=item B<--filter-metric> + +Filter metrics (Can be: 'ConnectionBpsEgress', 'ConnectionBpsIngress', +'ConnectionPpsEgress', 'ConnectionPpsIngress', 'ConnectionLightLevelTx', 'ConnectionLightLevelRx') +(Can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{bandwidth}, %{connectionName} + +=item B<--critical-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{bandwidth}, %{connectionName} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be 'connection-egress', 'connection-ingress', +'connection-packets-egress', 'connection-packets-ingress', +'connection-ligh-level-outbound', 'connection-ligh-level-inbound. + +=back + +=cut diff --git a/src/cloud/aws/directconnect/mode/discovery.pm b/src/cloud/aws/directconnect/mode/discovery.pm new file mode 100644 index 000000000..9dba86ed2 --- /dev/null +++ b/src/cloud/aws/directconnect/mode/discovery.pm @@ -0,0 +1,104 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::directconnect::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'prettify' => { name => 'prettify' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $connections = $options{custom}->directconnect_describe_connections(); + + foreach my $connection_id (keys %$connections) { + my %connection = (type => 'connection'); + + $connection{id} = $connection_id; + $connection{name} = $connections->{$connection_id}->{name}; + $connection{state} = $connections->{$connection_id}->{state}; + $connection{bandwidth} = $connections->{$connection_id}->{bandwidth}; + push @disco_data, \%connection; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +AWS Direct Connect discovery. + +=over 8 + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/src/cloud/aws/directconnect/mode/listconnections.pm b/src/cloud/aws/directconnect/mode/listconnections.pm new file mode 100644 index 000000000..0933ea4b2 --- /dev/null +++ b/src/cloud/aws/directconnect/mode/listconnections.pm @@ -0,0 +1,103 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::directconnect::mode::listconnections; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + return $options{custom}->directconnect_describe_connections(); +} + +sub run { + my ($self, %options) = @_; + + my $connections = $self->manage_selection(%options); + foreach my $connection_id (keys %$connections) { + $self->{output}->output_add( + long_msg => sprintf( + '[id: %s][name: %s][state: %s]', + $connection_id, + $connections->{$connection_id}->{name}, + $connections->{$connection_id}->{state} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List connections:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['id', 'name', 'state']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $connections = $self->manage_selection(%options); + foreach my $connection_id (keys %$connections) { + $self->{output}->add_disco_entry( + id => $connection_id, + name => $connections->{$connection_id}->{name}, + state => $connections->{$connection_id}->{state} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List direct connections. + +=over 8 + +=back + +=cut diff --git a/src/cloud/aws/directconnect/mode/listvirtualinterfaces.pm b/src/cloud/aws/directconnect/mode/listvirtualinterfaces.pm new file mode 100644 index 000000000..6da2483da --- /dev/null +++ b/src/cloud/aws/directconnect/mode/listvirtualinterfaces.pm @@ -0,0 +1,114 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::directconnect::mode::listvirtualinterfaces; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $connections = $options{custom}->directconnect_describe_connections(); + my $interfaces = $options{custom}->directconnect_describe_virtual_interfaces(); + + my $results = []; + foreach my $vid (keys %$interfaces) { + push @$results, { + connectionId => $interfaces->{$vid}->{connectionId}, + connectionName => $connections->{ $interfaces->{$vid}->{connectionId} }->{name}, + virtualInterfaceId => $vid, + virtualInterfaceName => $interfaces->{$vid}->{name}, + virtualInterfaceState => $interfaces->{$vid}->{state} + }; + } + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->output_add( + long_msg => sprintf( + '[connectionId: %s][connectionName: %s][virtualInterfaceId: %s][virtualInterfaceName: %s][virtualInterfaceState: %s]', + $_->{connectionId}, + $_->{connectionName}, + $_->{virtualInterfaceId}, + $_->{virtualInterfaceName}, + $_->{virtualInterfaceState} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List virtual interfaces:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['virtualInterfaceId', 'virtualInterfaceName', 'connectionName', 'connectionId', 'virtualInterfaceState']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->add_disco_entry(%$_); + } +} + +1; + +__END__ + +=head1 MODE + +List virtual interfaces. + +=over 8 + +=back + +=cut diff --git a/src/cloud/aws/directconnect/mode/virtualinterfaces.pm b/src/cloud/aws/directconnect/mode/virtualinterfaces.pm new file mode 100644 index 000000000..e616440c8 --- /dev/null +++ b/src/cloud/aws/directconnect/mode/virtualinterfaces.pm @@ -0,0 +1,245 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::directconnect::mode::virtualinterfaces; + +use base qw(cloud::aws::custom::mode); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + extra_params => { + message_multiple => 'All virtual interfaces are ok' + }, + metrics => { + VirtualInterfaceBpsEgress => { + output => 'outbound data', + label => 'virtual-interface-egress', + nlabel => { + absolute => 'virtual_interface.egress.bitspersecond', + }, + unit => 'bps' + }, + VirtualInterfaceBpsIngress => { + output => 'inbound data', + label => 'virtual-interface-ingress', + nlabel => { + absolute => 'virtual_interface.ingress.bitspersecond', + }, + unit => 'bps' + }, + VirtualInterfacePpsEgress => { + output => 'outbound packets data', + label => 'virtual-interface-packets-egress', + nlabel => { + absolute => 'virtual_interface.egress.packets.persecond', + }, + unit => '/s' + }, + VirtualInterfacePpsIngress => { + output => 'inbound packet data', + label => 'virtual-interface-packets-ingress', + nlabel => { + absolute => 'virtual_interface.ingress.packets.persecond', + }, + unit => '/s' + } + } + }; + + return $metrics_mapping; +} + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf('state: %s [vlan: %s, type: %s]', $self->{result_values}->{state}, $self->{result_values}->{vlan}, $self->{result_values}->{type}); +} + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "connection '" . $options{instance_value}->{connectionName} . "' virtual interface '" . $options{instance_value}->{virtualInterfaceName} . "' "; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking connection '" . $options{instance_value}->{connectionName} . "' virtual interface '" . $options{instance_value}->{virtualInterfaceName} . "'"; +} + +sub prefix_statistics_output { + my ($self, %options) = @_; + + return "statistic '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->SUPER::set_counters(%options); + + unshift @{$self->{maps_counters_type}->[0]->{group}}, { + name => 'status', + type => 0, skipped_code => { -10 => 1 } + }; + + $self->{maps_counters}->{status} = [ + { label => 'status', type => 2, set => { + key_values => [ { name => 'state' }, { name => 'vlan' }, { name => 'type' }, { name => 'connectionName' }, { name => 'virtualInterfaceName' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-connection-id:s' => { name => 'filter_connection_id' }, + 'filter-virtual-interface-id:s' => { name => 'filter_virtual_interface_id' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $connections = $options{custom}->directconnect_describe_connections(); + my $interfaces = $options{custom}->directconnect_describe_virtual_interfaces(); + + foreach my $vid (keys %$interfaces) { + next if (defined($self->{option_results}->{filter_virtual_interface_id}) && $self->{option_results}->{filter_virtual_interface_id} ne '' + && $vid !~ /$self->{option_results}->{filter_virtual_interface_id}/); + next if (defined($self->{option_results}->{filter_connection_id}) && $self->{option_results}->{filter_connection_id} ne '' + && $interfaces->{$vid}->{connectionId} !~ /$self->{option_results}->{filter_connection_id}/); + + my $key = $connections->{ $interfaces->{$vid}->{connectionId} }->{name} . $self->{output}->get_instance_perfdata_separator() . $interfaces->{$vid}->{name}; + + $self->{metrics}->{$key} = { + connectionName => $connections->{ $interfaces->{$vid}->{connectionId} }->{name}, + virtualInterfaceName => $interfaces->{$vid}->{name}, + status => { + connectionName => $connections->{ $interfaces->{$vid}->{connectionId} }->{name}, + virtualInterfaceName => $interfaces->{$vid}->{name}, + type => $interfaces->{$vid}->{type}, + vlan => $interfaces->{$vid}->{vlan}, + state => $interfaces->{$vid}->{state} + }, + statistics => {} + }; + + my $cw_metrics = $options{custom}->cloudwatch_get_metrics( + namespace => 'AWS/DX', + dimensions => [ { Name => 'ConnectionId', Value => $interfaces->{$vid}->{connectionId} }, { Name => 'VirtualInterfaceId', Value => $vid } ], + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{aws_timeframe}, + period => $self->{aws_period} + ); + + foreach my $metric (@{$self->{aws_metrics}}) { + foreach my $statistic (@{$self->{aws_statistics}}) { + next if (!defined($cw_metrics->{$metric}->{lc($statistic)}) && + !defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$key}->{display} = $interfaces->{$vid}->{name}; + $self->{metrics}->{$key}->{statistics}->{lc($statistic)}->{display} = $statistic; + $self->{metrics}->{$key}->{statistics}->{lc($statistic)}->{timeframe} = $self->{aws_timeframe}; + $self->{metrics}->{$key}->{statistics}->{lc($statistic)}->{$metric} = + defined($cw_metrics->{$metric}->{lc($statistic)}) ? + $cw_metrics->{$metric}->{lc($statistic)} : 0; + } + } + } + + if (scalar(keys %{$self->{metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No virtual interface found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check direct connect virtual interfaces. + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::directconnect::plugin --custommode=paws --mode=virtual-interfaces --region='eu-west-1' +--filter-metric='VirtualInterfaceBpsEgress' --statistic='average' --critical-virtual-interface-egress='10Mb' --verbose + +See 'https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html' for more informations. + +Default statistic: 'average' / All satistics are valid. + +=over 8 + +=item B<--filter-connection-id> + +Filter connection id (can be a regexp). + +=item B<--filter-virtual-interface-id> + +Filter virtual interface id (can be a regexp). + +=item B<--filter-metric> + +Filter metrics (Can be: 'VirtualInterfaceBpsEgress', 'VirtualInterfaceBpsIngress', +'VirtualInterfacePpsEgress', 'VirtualInterfacePpsIngress') +(Can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{vlan}, %{type}, %{virtualInterfaceId} + +=item B<--critical-status> + +Set critical threshold for status. +Can used special variables like: %{state}, %{vlan}, %{type}, %{virtualInterfaceId} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be 'virtual-interface-egress', 'virtual-interface-ingress', +'virtual-interface-packets-egress', 'virtual-interface-packets-ingress'. + +=back + +=cut diff --git a/src/cloud/aws/directconnect/plugin.pm b/src/cloud/aws/directconnect/plugin.pm new file mode 100644 index 000000000..2f905365d --- /dev/null +++ b/src/cloud/aws/directconnect/plugin.pm @@ -0,0 +1,53 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::directconnect::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{modes} = { + 'connections' => 'cloud::aws::directconnect::mode::connections', + 'discovery' => 'cloud::aws::directconnect::mode::discovery', + 'list-connections' => 'cloud::aws::directconnect::mode::listconnections', + 'list-virtual-interfaces' => 'cloud::aws::directconnect::mode::listvirtualinterfaces', + 'virtual-interfaces' => 'cloud::aws::directconnect::mode::virtualinterfaces' + }; + + $self->{custom_modes}->{paws} = 'cloud::aws::custom::paws'; + $self->{custom_modes}->{awscli} = 'cloud::aws::custom::awscli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Amazon Direct Connect. + +=cut From cbd3818393c80e2c53555fe614306e438e4093fb Mon Sep 17 00:00:00 2001 From: itoussies <65223458+itoussies@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:45:58 +0200 Subject: [PATCH 402/447] (plugin) cloud::aws::custom::paws - fix --- src/cloud/aws/custom/paws.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cloud/aws/custom/paws.pm b/src/cloud/aws/custom/paws.pm index 2a30b1b12..c9fe895a8 100644 --- a/src/cloud/aws/custom/paws.pm +++ b/src/cloud/aws/custom/paws.pm @@ -798,7 +798,7 @@ sub directconnect_describe_connections { my $connections = $ec->DescribeConnections(); foreach (@{$connections->{Connections}}) { - $results->{ $_->{ConnectionId} } = { { + $results->{ $_->{ConnectionId} } = { name => $_->{ConnectionName}, state => $_->{ConnectionState}, bandwidth => $_->{Bandwidth} From ab787eb54316f615e620b554905ef8bc7a4e0854 Mon Sep 17 00:00:00 2001 From: Thibault S <48209914+thibaults-centreon@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:00:47 +0200 Subject: [PATCH 403/447] (plugin) hardware::devices::hms::netbiter::argos::restapi - new (#4352) hardware::devices::hms::netbiter::argos::restapi - new --- .../deb.json | 6 + .../pkg.json | 9 + .../rpm.json | 6 + .../hms/netbiter/argos/restapi/custom/api.pm | 306 ++++++++++++++++++ .../hms/netbiter/argos/restapi/mode/alarms.pm | 247 ++++++++++++++ .../netbiter/argos/restapi/mode/discovery.pm | 88 +++++ .../argos/restapi/mode/listsensors.pm | 118 +++++++ .../netbiter/argos/restapi/mode/sensors.pm | 182 +++++++++++ .../hms/netbiter/argos/restapi/plugin.pm | 52 +++ 9 files changed, 1014 insertions(+) create mode 100644 packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/deb.json create mode 100644 packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/pkg.json create mode 100644 packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/rpm.json create mode 100644 src/hardware/devices/hms/netbiter/argos/restapi/custom/api.pm create mode 100644 src/hardware/devices/hms/netbiter/argos/restapi/mode/alarms.pm create mode 100644 src/hardware/devices/hms/netbiter/argos/restapi/mode/discovery.pm create mode 100644 src/hardware/devices/hms/netbiter/argos/restapi/mode/listsensors.pm create mode 100644 src/hardware/devices/hms/netbiter/argos/restapi/mode/sensors.pm create mode 100644 src/hardware/devices/hms/netbiter/argos/restapi/plugin.pm diff --git a/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/deb.json b/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/deb.json new file mode 100644 index 000000000..0dd397141 --- /dev/null +++ b/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/deb.json @@ -0,0 +1,6 @@ +{ + "dependencies": [ + "libdatetime-perl", + "libdatetime-format-dateparse-perl" + ] +} diff --git a/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/pkg.json b/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/pkg.json new file mode 100644 index 000000000..56dcdf44b --- /dev/null +++ b/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/pkg.json @@ -0,0 +1,9 @@ +{ + "pkg_name": "centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi", + "pkg_summary": "Centreon Plugin to monitor HMS/Ewon Netbiter devices using Argos Rest Api", + "plugin_name": "centreon_hms_netbiter_argos_restapi.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "hardware/devices/hms/netbiter/argos/restapi" + ] +} diff --git a/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/rpm.json b/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/rpm.json new file mode 100644 index 000000000..1061b6c45 --- /dev/null +++ b/packaging/centreon-plugin-Hardware-Devices-Hms-Netbiter-Argos-Restapi/rpm.json @@ -0,0 +1,6 @@ +{ + "dependencies": [ + "perl(DateTime)", + "perl(Date::Parse)" + ] +} diff --git a/src/hardware/devices/hms/netbiter/argos/restapi/custom/api.pm b/src/hardware/devices/hms/netbiter/argos/restapi/custom/api.pm new file mode 100644 index 000000000..577ead319 --- /dev/null +++ b/src/hardware/devices/hms/netbiter/argos/restapi/custom/api.pm @@ -0,0 +1,306 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::devices::hms::netbiter::argos::restapi::custom::api; + +use strict; +use warnings; +use DateTime; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'access-key:s' => { name => 'access_key' }, + 'api-endpoint:s' => { name => 'api_endpoint' }, + 'api-password:s' => { name => 'api_password' }, + 'api-username:s' => { name => 'api_username' }, + 'force-cache-reload' => { name => 'force_cache_reload' }, + 'hostname:s' => { name => 'hostname' }, + 'port:s' => { name => 'port' }, + 'proto:s' => { name => 'proto' }, + 'reload-cache-time:s' => { name => 'reload_cache_time' }, + 'timeout:s' => { name => 'timeout' } + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl'); + $self->{cache_auth} = centreon::plugins::statefile->new(%options); + $self->{cache_sensors} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : 'api.netbiter.net'; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{api_endpoint} = (defined($self->{option_results}->{api_endpoint})) ? $self->{option_results}->{api_endpoint} : '/operation/v1/rest/json'; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : ''; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; + $self->{access_key} = (defined($self->{option_results}->{access_key})) ? $self->{option_results}->{access_key} : ''; + $self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? $self->{option_results}->{reload_cache_time} : 3600; + $self->{force_cache_reload} = (defined($self->{option_results}->{force_cache_reload})) ? $self->{option_results}->{force_cache_reload} : undef; + + if ( !(($self->{api_username} ne '' && $self->{api_password} ne '') || ($self->{access_key} ne '')) ) { + $self->{output}->add_option_msg(short_msg => 'At least one of --api-username / --api-password (login) ; or --access-key must be set'); + $self->{output}->option_exit(); + } + + $self->{cache_auth}->check_options(option_results => $self->{option_results}); + $self->{cache_sensors}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = '%{http_code} < 200 or %{http_code} > 400'; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub convert_iso8601_to_epoch { + my ($self, %options) = @_; + + if ($options{time_string} =~ /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/) { + my $dt = DateTime->new( + year => $1, + month => $2, + day => $3, + hour => $4, + minute => $5, + second => $6 + ); + + my $epoch_time = $dt->epoch(); + return $epoch_time; + } + + $self->{output}->add_option_msg(short_msg => "Wrong date format: $options{time_string}"); + $self->{output}->option_exit(); + +} + +sub get_access_key { + my ($self, %options) = @_; + + my $has_cache_file = $self->{cache_auth}->read(statefile => 'netbiter_argos_api_' . md5_hex($self->{hostname}) . '_' . $self->{cache_key}); + my $expires_on = $self->{cache_auth}->get(name => 'expires_on'); + my $access_key = $self->{cache_auth}->get(name => 'access_key'); + if ( $has_cache_file == 0 || !defined($access_key) || (($expires_on - time()) < 10) ) { + my $login; + if ($self->{api_username} ne '') { + $login = { userName => $self->{api_username}, password => $self->{api_password} }; + } + my $post_json = JSON::XS->new->utf8->encode($login); + + $self->settings(); + + my $content = $self->{http}->request( + method => 'POST', + header => ['Content-type: application/json'], + query_form_post => $post_json, + url_path => $self->{api_endpoint} . '/user/authenticate' + ); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "Authentication endpoint returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error_code})) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Authentication endpoint returns error code '" . $decoded->{error_code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + $access_key = $decoded->{access_key}; + my $expires_on = $self->convert_iso8601_to_epoch(time_string => $decoded->{expires}); + my $datas = { last_timestamp => time(), access_key => $decoded->{accessKey}, expires_on => $expires_on }; + $self->{cache_auth}->write(data => $datas); + } + + return $access_key; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{access_key})) { + $self->{access_key} = $self->get_access_key(statefile => $self->{cache}); + } + + $self->settings(); + my $url_path = $self->{api_endpoint} . $options{request}; + my $parameters = defined($options{get_params}) ? $options{get_params} : []; + my $response = $self->{http}->request( + method => 'GET', + get_param => [ 'accesskey=' . $self->{access_key}, @$parameters ], + url_path => $url_path + ); + # check rate limit => to do + #my $rate_limit = $self->{http}->get_header(name => 'argos-ratelimit-remaining'); + if (!defined($response) || $response eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->decode($response); + }; + + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + return $decoded; +} + +sub list_sensors { + my ($self, %options) = @_; + # Results are cached to avoid too many API calls + my $has_cache_file = $self->{cache_sensors}->read(statefile => 'netbiter_cache_sensors_' . md5_hex($options{system_id})); + my $response = $self->{cache_sensors}->get(name => 'response'); + my $freshness = defined($self->{cache_sensors}->get(name => 'update_time')) ? time() - $self->{cache_sensors}->get(name => 'update_time') : undef; + $self->{force_cache_reload} = 1 if defined($options{force}); + + if ( $has_cache_file == 0 || !defined($response) || (defined($freshness)) && ($freshness > $self->{reload_cache_time}) || defined($self->{force_cache_reload}) ) { + my $request = '/system/' . $options{system_id} . '/log/config'; + $response = $self->request_api(request => $request); + } + + $self->{cache_sensors}->write(data => { + update_time => time(), + response => $response + }); + + return $response +} + +1; + +__END__ + +=head1 NAME + +Netbiter Argos RestAPI + +=head1 REST API OPTIONS + +Netbiter Argos RestAPI + +=over 8 + +=item B<--hostname> + +Argos API hostname (Default: api.netbiter.net). + +=item B<--port> + +Port used (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--api-endpoint> + +Argos API requests endpoint (Default: '/operation/v1/rest/json') + +=item B<--access-key> + +For Access Key "direct" authentication method. +Example: --access-key='ABCDEFG1234567890' + +=item B<--api-username> + +For Username/Password authentication method. +Must be used with --api-password option. + +=item B<--api-password> + +For Username/Password authentication method. +Must be used with --api-username option. + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/src/hardware/devices/hms/netbiter/argos/restapi/mode/alarms.pm b/src/hardware/devices/hms/netbiter/argos/restapi/mode/alarms.pm new file mode 100644 index 000000000..8bdb9a41d --- /dev/null +++ b/src/hardware/devices/hms/netbiter/argos/restapi/mode/alarms.pm @@ -0,0 +1,247 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and cluster monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::devices::hms::netbiter::argos::restapi::mode::alarms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Date::Parse; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Alarms: '; +} + +sub prefix_alarms_output { + my ($self, %options) = @_; + return sprintf('[%s] Alarm name: "%s", Device name: "%s" ', $options{instance_value}->{timestamp}, $options{instance_value}->{display}, $options{instance_value}->{device_name}); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }, + { name => 'alarms', type => 1, cb_prefix_output => 'prefix_alarms_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'alarms-total', nlabel => 'alarms.total.count', set => { + key_values => [ { name => 'total' } ], + output_template => 'total current: %s', + perfdatas => [ { template => '%d', min => 0 } ] + } + } + ]; + + $self->{maps_counters}->{alarms} = [ + { label => 'alarm-active', + type => 2, + critical_default => '%{active} =~ "true"', + set => { + key_values => [ { name => 'active' } ], + output_template => 'active: %s', + display_ok => 0, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'alarm-acked', + type => 2, + warning_default => '%{acked} =~ "false"', + set => { + key_values => [ { name => 'acked' } ], + output_template => 'acknowledged: %s', + display_ok => 0, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'alarm-duration', nlabel => 'alarm.duration.seconds', + type => 1, + set => { + key_values => [ { name => 'duration' }, { name => 'display' } ], + output_template => 'duration: %ds', + display_ok => 0, + perfdatas => [ { template => '%d', min => 0, unit => 's', label_extra_instance => 1, instance_use => 'display' } ] + } + }, + { label => 'alarm-severity', + type => 1, + set => { + key_values => [ { name => 'severity' } ], + output_template => 'severity: %s', + display_ok => 0, + closure_custom_perfdata => sub { return 0; } + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-acked' => { name => 'filter_acked' }, + 'filter-active' => { name => 'filter_active' }, + 'filter-severity:s' => { name => 'filter_severity' }, + 'system-id:s' => { name => 'system_id' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (defined($self->{option_results}->{filter_severity}) && $self->{option_results}->{filter_severity} ne '') { + if (lc($self->{option_results}->{filter_severity}) !~ '/critical|major|minor|warning|cleared/') { + $self->{output}->add_option_msg(short_msg => 'Unknown severity "' . $self->{option_results}->{filter_severity} . '"'); + $self->{output}->option_exit(); + } + $self->{severity} = lc($self->{option_results}->{filter_severity}); + } + if (!(defined($self->{option_results}->{system_id})) || $self->{option_results}->{system_id} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --system-id option."); + $self->{output}->option_exit(); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global}->{total} = 0; + + my $severity_mapping = { + critical => '1', + major => '2', + minor => '3', + warning => '4', + cleared => '5' + }; + my $active_alarms = 'false'; + my $url = '/system/' . $self->{option_results}->{system_id} . '/alarm'; + my $get_params; + + if (defined($self->{severity})) { + my $severity_level = $severity_mapping->{$self->{severity}}; + push @$get_params, 'severity=' . $severity_level; + } + if (defined($self->{option_results}->{filter_acked})) { + push @$get_params, 'acked=false'; + } + if (defined($self->{option_results}->{filter_active})) { + $active_alarms = 'true'; + } + push @$get_params, 'active=' . $active_alarms; + + my $result = $options{custom}->request_api( + request => $url, + get_params => $get_params + ); + + foreach (@{$result}) { + my $timestamp = str2time($_->{timestamp}, 'GMT'); + $self->{alarms}->{$_->{id}} = { + acked => ($_->{acked}) ? 'true' : 'false', + active => ($_->{active}) ? 'true' : 'false', + device_name => $_->{deviceName}, + duration => time() - $timestamp, + display => $_->{name}, + id => $_->{id}, + severity => $_->{severity}, + timestamp => POSIX::strftime('%d-%m-%Y %H:%M:%S %Z', localtime($timestamp)) + }; + } + + $self->{global}->{total} = scalar (keys %{$self->{alarms}}); +} + +1; + +__END__ + +=head1 MODE + +Check Netbiter alarms using Argos RestAPI. + +Example: +perl centreon_plugins.pl --plugin=hardware::devices::hms::netbiter::argos::restapi::plugin --mode=alarms +--access-key='ABCDEFG1234567890' --system-id='XYZ123' --filter-active --verbose + +More information on'https://apidocs.netbiter.net/?page=methods&show=getSystemAlarms'. + +=over 8 + +=item B<--system-id> + +Set the Netbiter Argos System ID (Mandatory). + +=item B<--filter-acked> + +Hide acknowledged alarms. + +=item B<--filter-active> + +Only show active alarms. + +=item B<--filter-severity> + +Only show alarms with a given severity level. +Can be: 'critical', 'major', 'minor', 'warning', 'cleared'. +Only one value can be set (no multiple values). + +=item B<--warning-active-status> + +Set warning threshold for active status (Default: ''). +Typical syntax: --warning-active-status='%{active} =~ "true"' + +=item B<--critical-active-status> + +Set critical threshold for active status (Default: '%{active} =~ "true"'). +Typical syntax: --critical-active-status='%{active} =~ "true"' + +=item B<--warning-acked-status> + +Set warning threshold for acked status (Default: '%{acked} =~ "false"'). +Typical syntax: --warning-acked-status='%{acked} =~ "false"' + +=item B<--critical-acked-status> + +Set critical threshold for acked status (Default: ''). +Typical syntax: --critical-acked-status='%{acked} =~ "false"' + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'warning-alarms-total' (count) 'critical-alarms-total' (count), +'warning-alarm-duration' (s), 'critical-alarm-duration' (s), +'warning-alarm-severity' (level from 0 to 5), critical-alarm-severity (level from 0 to 5). + +=back + +=cut diff --git a/src/hardware/devices/hms/netbiter/argos/restapi/mode/discovery.pm b/src/hardware/devices/hms/netbiter/argos/restapi/mode/discovery.pm new file mode 100644 index 000000000..db69736b4 --- /dev/null +++ b/src/hardware/devices/hms/netbiter/argos/restapi/mode/discovery.pm @@ -0,0 +1,88 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::devices::hms::netbiter::argos::restapi::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + "prettify" => { name => 'prettify' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $results = $options{custom}->request_api(request => '/system'); + $disco_stats->{results} = $results; + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = scalar(@{$disco_stats->{results}}); + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=back + +=cut \ No newline at end of file diff --git a/src/hardware/devices/hms/netbiter/argos/restapi/mode/listsensors.pm b/src/hardware/devices/hms/netbiter/argos/restapi/mode/listsensors.pm new file mode 100644 index 000000000..6b93243df --- /dev/null +++ b/src/hardware/devices/hms/netbiter/argos/restapi/mode/listsensors.pm @@ -0,0 +1,118 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::devices::hms::netbiter::argos::restapi::mode::listsensors; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + "system-id:s" => { name => 'system_id' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!(defined($self->{option_results}->{system_id})) || $self->{option_results}->{system_id} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --system-id option."); + $self->{output}->option_exit(); + } +} + +sub manage_selection { + my ($self, %options) = @_; + return $options{custom}->list_sensors(system_id => $self->{option_results}->{system_id}, force => 1); +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + next if ($_->{pointType} ne 'R'); + $self->{output}->output_add( + long_msg => sprintf( + '[id: %s][name: %s][device name: %s][unit: %s][log interval: %s]', + $_->{id}, + $_->{name}, + $_->{deviceName}, + $_->{unit}, + $_->{logInterval} + )); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List sensors:' + ); + + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['id', 'name', 'deviceName', 'unit', 'logInterval']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->add_disco_entry( + deviceName => $_->{deviceName}, + id => $_->{id}, + logInterval => $_->{logInterval}, + name => $_->{name}, + unit => defined($_->{unit}) ? $_->{unit} : '' + ); + } +} + +1; + +__END__ + +=head1 MODE + +List Netbiter log sensors using Argos RestAPI. + +=over 8 + +=item B<--system-id> + +Set the Netbiter Argos System ID (Mandatory). + +=back + +=cut \ No newline at end of file diff --git a/src/hardware/devices/hms/netbiter/argos/restapi/mode/sensors.pm b/src/hardware/devices/hms/netbiter/argos/restapi/mode/sensors.pm new file mode 100644 index 000000000..03d444821 --- /dev/null +++ b/src/hardware/devices/hms/netbiter/argos/restapi/mode/sensors.pm @@ -0,0 +1,182 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and cluster monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::devices::hms::netbiter::argos::restapi::mode::sensors; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Date::Parse; + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf('Device: %s, Name: %s, Value: %s%s (%s)', + $self->{result_values}->{device_name}, + $self->{result_values}->{display}, + $self->{result_values}->{value}, + $self->{result_values}->{unit}, + $self->{result_values}->{timestamp} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'sensors', type => 1, message_multiple => 'All sensors are OK' }, + ]; + + $self->{maps_counters}->{sensors} = [ + { label => 'sensor-value', nlabel => 'sensor.reading.count', set => { + key_values => [ { name => 'value' }, { name => 'display' }, { name => 'device_name' }, { name => 'timestamp' }, { name => 'unit' } ], + closure_custom_output => $self->can('custom_status_output'), + output_template => "value : %s", + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => $self->{result_values}->{unit}, + instances => $self->{result_values}->{display}, + value => sprintf('%.1f', $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}) + ); + } + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-device:s' => { name => 'filter_device' }, + 'filter-name:s' => { name => 'filter_name' }, + 'filter-id:s' => { name => 'filter_id' }, + 'system-id:s' => { name => 'system_id' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!(defined($self->{option_results}->{system_id})) || $self->{option_results}->{system_id} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --system-id option."); + $self->{output}->option_exit(); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $sensors = $options{custom}->list_sensors(system_id => $self->{option_results}->{system_id}); + + foreach (@{$sensors}) { + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $_->{id} !~ /$self->{option_results}->{filter_id}/); + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $_->{name} !~ /$self->{option_results}->{filter_name}/); + next if (defined($self->{option_results}->{filter_device}) && $self->{option_results}->{filter_device} ne '' && + $_->{deviceName} !~ /$self->{option_results}->{filter_device}/); + + my $url = '/system/' . $self->{option_results}->{system_id} . '/log/' . $_->{id}; + my $result = $options{custom}->request_api( + request => $url, + get_params => [ 'limitrows=1' ] + ); + + if (scalar(@{$result}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'Skipping ' . $_->{name} . ' (no value)'); + next + } + + foreach my $entry (@{$result}) { + my $timestamp = $options{custom}->convert_iso8601_to_epoch(time_string => $entry->{timestamp}); + $self->{sensors}->{$_->{id}} = { + device_name => $_->{deviceName}, + display => $_->{name}, + timestamp => POSIX::strftime('%Y-%m-%d %H:%M:%S %Z', localtime($timestamp)), + unit => $_->{unit}, + value => $entry->{value} + } + } + } + + if (scalar(keys %{$self->{sensors}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No sensor found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Netbiter sensors values using Argos RestAPI. + +Example: +perl centreon_plugins.pl --plugin=hardware::devices::hms::netbiter::argos::restapi::plugin --mode=sensors +--access-key='ABCDEFG1234567890' --system-id='XYZ123' --filter-name='My Sensor' --verbose + +More information on'https://apidocs.netbiter.net/?page=methods&show=getSystemLoggedValues'. + +=over 8 + +=item B<--system-id> + +Set the Netbiter Argos System ID (Mandatory). + +=item B<--filter-id> + +Filter by sensor ID (Regexp can be used). +Example: --filter-id='^1234.5678$' + +=item B<--filter-device> + +Filter by device name (Regexp can be used). +Example: --filter-device='^ZONE(1|2)$' + +=item B<--filter-name> + +Filter by sensor name (Regexp can be used). +Example: --filter-name='^temperature_(in|out)$' + +=item B<--warning-sensor-value> + +Warning threshold. + +=item B<--critical-sensor-value> + +Critical threshold. + +=back + +=cut diff --git a/src/hardware/devices/hms/netbiter/argos/restapi/plugin.pm b/src/hardware/devices/hms/netbiter/argos/restapi/plugin.pm new file mode 100644 index 000000000..df2185bb3 --- /dev/null +++ b/src/hardware/devices/hms/netbiter/argos/restapi/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::devices::hms::netbiter::argos::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $self->{modes} = { + 'alarms' => 'hardware::devices::hms::netbiter::argos::restapi::mode::alarms', + 'discovery' => 'hardware::devices::hms::netbiter::argos::restapi::mode::discovery', + 'list-sensors' => 'hardware::devices::hms::netbiter::argos::restapi::mode::listsensors', + 'sensors' => 'hardware::devices::hms::netbiter::argos::restapi::mode::sensors' + }; + + $self->{custom_modes}->{restapi} = 'hardware::devices::hms::netbiter::argos::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Netbiter IoT devices using Argos RestAPI. + +=cut From 2702d91a76b34b278181be71ac052ff8ed9157ee Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 28 Apr 2023 10:07:58 +0200 Subject: [PATCH 404/447] (plugin) network::stormshield::snmp - mode vpn-status fix threshold status (#4393) --- src/network/stormshield/snmp/mode/vpnstatus.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/stormshield/snmp/mode/vpnstatus.pm b/src/network/stormshield/snmp/mode/vpnstatus.pm index 651c40806..ae122de87 100644 --- a/src/network/stormshield/snmp/mode/vpnstatus.pm +++ b/src/network/stormshield/snmp/mode/vpnstatus.pm @@ -26,6 +26,7 @@ use strict; use warnings; use centreon::plugins::misc; use Digest::MD5 qw(md5_hex); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_traffic_perfdata { my ($self, %options) = @_; @@ -86,10 +87,9 @@ sub set_counters { key_values => [ { name => 'state' }, { name => 'ipSrc' }, { name => 'ipDst' } ], - closure_custom_calc => $self->can('custom_status_calc'), output_template => 'state: %s', closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => $self->can('custom_threshold_output') + closure_custom_threshold_check => \&catalog_status_threshold_ng } }, { label => 'traffic', nlabel => 'vpn.traffic.bitspersecond', set => { From 2bf68587a509cb5b983bcd8d9ef1abedb6517134 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 28 Apr 2023 10:08:10 +0200 Subject: [PATCH 405/447] (plugin) storage::ibm::storwize::ssh - mode hardware add option --add-name-instance (#4391) --- src/centreon/plugins/templates/hardware.pm | 4 +++- .../ibm/storwize/ssh/mode/components/array.pm | 10 ++++++++-- .../ibm/storwize/ssh/mode/components/drive.pm | 2 +- .../ibm/storwize/ssh/mode/components/enclosure.pm | 4 ++-- .../ssh/mode/components/enclosurebattery.pm | 9 +++++++-- .../ssh/mode/components/enclosurecanister.pm | 4 ++-- .../storwize/ssh/mode/components/enclosurepsu.pm | 4 ++-- .../ibm/storwize/ssh/mode/components/host.pm | 6 +++--- .../ibm/storwize/ssh/mode/components/mdisk.pm | 6 +++--- .../ibm/storwize/ssh/mode/components/node.pm | 6 +++--- .../ibm/storwize/ssh/mode/components/portfc.pm | 9 +++++---- .../ibm/storwize/ssh/mode/components/portsas.pm | 9 +++++---- .../ibm/storwize/ssh/mode/components/quorum.pm | 12 +++++++++--- .../storwize/ssh/mode/components/systemstats.pm | 10 +++++++--- .../ibm/storwize/ssh/mode/components/vdisk.pm | 12 +++++++++--- src/storage/ibm/storwize/ssh/mode/hardware.pm | 14 +++++++++----- 16 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/centreon/plugins/templates/hardware.pm b/src/centreon/plugins/templates/hardware.pm index 3f480e68a..923ef69a3 100644 --- a/src/centreon/plugins/templates/hardware.pm +++ b/src/centreon/plugins/templates/hardware.pm @@ -453,7 +453,9 @@ sub get_severity { my ($self, %options) = @_; my $status = 'UNKNOWN'; # default - foreach (@{$self->{overload_th}}) { + $options{instance} .= '#' . $options{name} if (defined($self->{option_results}->{add_name_instance}) && defined($options{name})); + + foreach (@{$self->{overload_th}}) { if ($options{section} =~ /$_->{section}/i) { if ($options{value} =~ /$_->{filter}/i && (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { diff --git a/src/storage/ibm/storwize/ssh/mode/components/array.pm b/src/storage/ibm/storwize/ssh/mode/components/array.pm index 84412d6e1..63e7d285f 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/array.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/array.pm @@ -41,7 +41,7 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'array', instance => $_->{mdisk_id})); + next if ($self->check_filter(section => 'array', instance => $_->{mdisk_id}, name => $_->{mdisk_name})); $self->{components}->{array}->{total}++; $self->{output}->output_add( @@ -52,7 +52,13 @@ sub check { $_->{mdisk_id} ) ); - my $exit = $self->get_severity(label => 'default', section => 'array', value => $_->{status}); + my $exit = $self->get_severity( + label => 'default', + section => 'array', + instance => $_->{mdisk_id}, + name => $_->{mdisk_name}, + value => $_->{status} + ); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/drive.pm b/src/storage/ibm/storwize/ssh/mode/components/drive.pm index 5d8656de0..237c487b4 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/drive.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/drive.pm @@ -51,7 +51,7 @@ sub check { $_->{id} ) ); - my $exit = $self->get_severity(label => 'default', section => 'drive', value => $_->{status}); + my $exit = $self->get_severity(label => 'default', section => 'drive', instance => $_->{id}, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/enclosure.pm b/src/storage/ibm/storwize/ssh/mode/components/enclosure.pm index 1f89e0091..d910f373b 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/enclosure.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/enclosure.pm @@ -46,13 +46,13 @@ sub check { $self->{output}->output_add( long_msg => sprintf( - "enclosure '%s' status is '%s' [instance: %s].", + "enclosure '%s' status is '%s' [instance: %s]", $_->{id}, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(label => 'default', section => 'enclosure', value => $_->{status}); + my $exit = $self->get_severity(label => 'default', section => 'enclosure', instance => $_->{id}, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm b/src/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm index 4a1bc03e8..9b1ec3c30 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm @@ -47,13 +47,18 @@ sub check { $self->{output}->output_add( long_msg => sprintf( - "enclosure battery '%s' status is '%s' [instance: %s].", + "enclosure battery '%s' status is '%s' [instance: %s]", $instance, $_->{status}, $instance ) ); - my $exit = $self->get_severity(label => 'default', section => 'enclosurebattery', value => $_->{status}); + my $exit = $self->get_severity( + label => 'default', + section => 'enclosurebattery', + instance => $instance, + value => $_->{status} + ); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm b/src/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm index 1ca5c304e..f7f96de0a 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm @@ -47,13 +47,13 @@ sub check { $self->{output}->output_add( long_msg => sprintf( - "enclosure canister '%s' status is '%s' [instance: %s].", + "enclosure canister '%s' status is '%s' [instance: %s]", $instance, $_->{status}, $instance ) ); - my $exit = $self->get_severity(label => 'default', section => 'enclosurecanister', value => $_->{status}); + my $exit = $self->get_severity(label => 'default', section => 'enclosurecanister', instance => $instance, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm b/src/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm index a9d54de73..807a6b0a4 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm @@ -47,13 +47,13 @@ sub check { $self->{output}->output_add( long_msg => sprintf( - "enclosure power supply '%s' status is '%s' [instance: %s].", + "enclosure power supply '%s' status is '%s' [instance: %s]", $instance, $_->{status}, $instance ) ); - my $exit = $self->get_severity(label => 'default', section => 'enclosurepsu', value => $_->{status}); + my $exit = $self->get_severity(label => 'default', section => 'enclosurepsu', instance => $instance, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/host.pm b/src/storage/ibm/storwize/ssh/mode/components/host.pm index 998cbae8e..1d286e7b8 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/host.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/host.pm @@ -41,18 +41,18 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'host', instance => $_->{id})); + next if ($self->check_filter(section => 'host', instance => $_->{id}, name => $_->{name})); $self->{components}->{host}->{total}++; $self->{output}->output_add( long_msg => sprintf( - "host '%s' status is '%s' [instance: %s].", + "host '%s' status is '%s' [instance: %s]", $_->{name}, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(label => 'default', section => 'host', value => $_->{status}); + my $exit = $self->get_severity(label => 'default', section => 'host',instance => $_->{id}, name => $_->{name}, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/mdisk.pm b/src/storage/ibm/storwize/ssh/mode/components/mdisk.pm index 4254cb4f5..292b68931 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/mdisk.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/mdisk.pm @@ -41,18 +41,18 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'mdisk', instance => $_->{id})); + next if ($self->check_filter(section => 'mdisk', instance => $_->{id}, name => $_->{name})); $self->{components}->{mdisk}->{total}++; $self->{output}->output_add( long_msg => sprintf( - "mdisk '%s' status is '%s' [instance: %s].", + "mdisk '%s' status is '%s' [instance: %s]", $_->{name}, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(section => 'mdisk', value => $_->{status}); + my $exit = $self->get_severity(section => 'mdisk', instance => $_->{id}, name => $_->{name}, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/node.pm b/src/storage/ibm/storwize/ssh/mode/components/node.pm index 27b58b24d..bef90b392 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/node.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/node.pm @@ -41,18 +41,18 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'node', instance => $_->{id})); + next if ($self->check_filter(section => 'node', instance => $_->{id}, name => $_->{name})); $self->{components}->{node}->{total}++; $self->{output}->output_add( long_msg => sprintf( - "node '%s' status is '%s' [instance: %s].", + "node '%s' status is '%s' [instance: %s]", $_->{name}, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(label => 'default', section => 'node', value => $_->{status}); + my $exit = $self->get_severity(label => 'default', section => 'node', instance => $_->{id}, name => $_->{name}, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/portfc.pm b/src/storage/ibm/storwize/ssh/mode/components/portfc.pm index c2ae85b2a..4ea13afc2 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/portfc.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/portfc.pm @@ -41,19 +41,20 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'portfc', instance => $_->{id})); + my $name = $_->{node_name} . "." . $_->{WWPN}; + + next if ($self->check_filter(section => 'portfc', instance => $_->{id}, name => $name)); $self->{components}->{portfc}->{total}++; - my $name = $_->{node_name} . "." . $_->{WWPN}; $self->{output}->output_add( long_msg => sprintf( - "portfc '%s' status is '%s' [instance: %s].", + "portfc '%s' status is '%s' [instance: %s]", $name, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(section => 'portfc', value => $_->{status}); + my $exit = $self->get_severity(section => 'portfc', instance => $_->{id}, name => $name, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/portsas.pm b/src/storage/ibm/storwize/ssh/mode/components/portsas.pm index b38809b23..27785038e 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/portsas.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/portsas.pm @@ -41,19 +41,20 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'portsas', instance => $_->{id})); + my $name = $_->{node_name} . '.' . $_->{WWPN}; + + next if ($self->check_filter(section => 'portsas', instance => $_->{id}, name => $name)); $self->{components}->{portsas}->{total}++; - my $name = $_->{node_name} . "." . $_->{WWPN}; $self->{output}->output_add( long_msg => sprintf( - "port sas '%s' status is '%s' [instance: %s].", + "port sas '%s' status is '%s' [instance: %s]", $name, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(section => 'portsas', value => $_->{status}); + my $exit = $self->get_severity(section => 'portsas', instance => $_->{id}, name => $name, value => $_->{status}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/quorum.pm b/src/storage/ibm/storwize/ssh/mode/components/quorum.pm index 10e20e06e..5561c191d 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/quorum.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/quorum.pm @@ -41,18 +41,24 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'quorum', instance => $_->{quorum_index})); + next if ($self->check_filter(section => 'quorum', instance => $_->{quorum_index}, name => $_->{controller_name})); $self->{components}->{quorum}->{total}++; $self->{output}->output_add( long_msg => sprintf( - "quorum '%s' status is '%s' [instance: %s].", + "quorum '%s' status is '%s' [instance: %s]", $_->{controller_name}, $_->{status}, $_->{quorum_index} ) ); - my $exit = $self->get_severity(label => 'default', section => 'quorum', value => $_->{status}); + my $exit = $self->get_severity( + label => 'default', + section => 'quorum', + instance => $_->{quorum_index}, + name => $_->{controller_name}, + value => $_->{status} + ); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/systemstats.pm b/src/storage/ibm/storwize/ssh/mode/components/systemstats.pm index 02143e629..d6dc46103 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/systemstats.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/systemstats.pm @@ -41,18 +41,22 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => '\s+'); foreach (@$result) { - next if ($self->check_filter(section => 'systemstats', instance => $_->{stat_name})); + next if ($self->check_filter(section => 'systemstats', instance => $_->{stat_name}, name => $_->{stat_name})); $self->{components}->{systemstats}->{total}++; $self->{output}->output_add( long_msg => sprintf( - "system stat '%s' value is '%s' [instance: %s].", + "system stat '%s' value is '%s' [instance: %s]", $_->{stat_name}, $_->{stat_current}, $_->{stat_name} ) ); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'systemstats', instance => $_->{stat_name}, value => $_->{stat_current}); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric( + section => 'systemstats', + instance => $_->{stat_name}, + value => $_->{stat_current} + ); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/components/vdisk.pm b/src/storage/ibm/storwize/ssh/mode/components/vdisk.pm index fa16fca6c..383e24b7b 100644 --- a/src/storage/ibm/storwize/ssh/mode/components/vdisk.pm +++ b/src/storage/ibm/storwize/ssh/mode/components/vdisk.pm @@ -41,18 +41,24 @@ sub check { my $result = $self->{custom}->get_hasharray(content => $content, delim => ':'); foreach (@$result) { - next if ($self->check_filter(section => 'vdisk', instance => $_->{id})); + next if ($self->check_filter(section => 'vdisk', instance => $_->{id}, name => $_->{name})); $self->{components}->{vdisk}->{total}++; $self->{output}->output_add( long_msg => sprintf( - "vdisk '%s' status is '%s' [instance: %s].", + "vdisk '%s' status is '%s' [instance: %s]", $_->{name}, $_->{status}, $_->{id} ) ); - my $exit = $self->get_severity(label => 'default', section => 'vdisk', value => $_->{status}); + my $exit = $self->get_severity( + label => 'default', + section => 'vdisk', + instance => $_->{id}, + name => $_->{name}, + value => $_->{status} + ); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, diff --git a/src/storage/ibm/storwize/ssh/mode/hardware.pm b/src/storage/ibm/storwize/ssh/mode/hardware.pm index 28da40c53..fc6d592a3 100644 --- a/src/storage/ibm/storwize/ssh/mode/hardware.pm +++ b/src/storage/ibm/storwize/ssh/mode/hardware.pm @@ -38,19 +38,19 @@ sub set_system { ['offline', 'CRITICAL'], ['degraded', 'WARNING'], ['excluded', 'OK'], # lsarray - ['mask', 'OK'], # lshost + ['mask', 'OK'] # lshost ], portfc => [ ['active', 'OK'], ['inactive_unconfigured', 'OK'], - ['.*', 'CRITICAL'], + ['.*', 'CRITICAL'] ], portsas => [ ['online', 'OK'], ['offline_unconfigured', 'OK'], ['excluded', 'OK'], ['offline', 'CRITICAL'], - ['degraded', 'WARNING'], + ['degraded', 'WARNING'] ], mdisk => [ ['online', 'OK'], @@ -58,8 +58,8 @@ sub set_system { ['offline', 'CRITICAL'], ['degraded_paths', 'WARNING'], ['degraded_ports', 'WARNING'], - ['degraded', 'WARNING'], - ], + ['degraded', 'WARNING'] + ] }; $self->{components_path} = 'storage::ibm::storwize::ssh::mode::components'; @@ -103,6 +103,10 @@ Which component to check (Default: '.*'). Can be: 'array', 'drive', 'enclosure', 'enclosurebattery', 'enclosurecanister', 'enclosurepsu', 'host', 'portfc', 'portsas', 'vdisk', 'node', 'quorum', 'mdisk', 'systemstats'. +=item B<--add-name-instance> + +Add literal description for instance value (used in filter, absent-problem and threshold options). + =item B<--filter> Exclude some parts (comma seperated list) (Example: --filter=host --filter=enclosurecanister) From ad747cb0efa5158b6e3c503fc48d93943e6b2a62 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 28 Apr 2023 10:08:21 +0200 Subject: [PATCH 406/447] (plugin) cloud::azure::database::sqldatabase - add modes cpu and memory (#4368) --- .../azure/database/sqldatabase/mode/cpu.pm | 149 ++++++++++++++++++ .../azure/database/sqldatabase/mode/memory.pm | 149 ++++++++++++++++++ .../azure/database/sqldatabase/plugin.pm | 2 + 3 files changed, 300 insertions(+) create mode 100644 src/cloud/azure/database/sqldatabase/mode/cpu.pm create mode 100644 src/cloud/azure/database/sqldatabase/mode/memory.pm diff --git a/src/cloud/azure/database/sqldatabase/mode/cpu.pm b/src/cloud/azure/database/sqldatabase/mode/cpu.pm new file mode 100644 index 000000000..08d183209 --- /dev/null +++ b/src/cloud/azure/database/sqldatabase/mode/cpu.pm @@ -0,0 +1,149 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::sqldatabase::mode::cpu; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'cpu_percent' => { + 'output' => 'CPU used percent', + 'label' => 'usage-percent', + 'nlabel' => 'sqldatabase.cpu.usage.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'server:s' => { name => 'server' } + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group and --server option OR --resource .'); + $self->{output}->option_exit(); + } + my $resource = $self->{option_results}->{resource}; + my $server = $self->{option_results}->{server}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.Sql\/servers\/(.*)\/databases\/(.*)$/) { + $resource_group = $1; + $server = $2; + $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = 'servers'; + $self->{az_resource_namespace} = 'Microsoft.Sql'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Maximum']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure SQL Database CPU. +Metrics are available with: +- Tier 'DTU based' - Basic, Standard, Premium +- vCore based model - General purpose & Business critical +- HyperScale + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::sqldatabase::plugin --mode=cpu --custommode=api +--resource= --resource-group= --server= --aggregation='maximum' +--warning-usage-percent='80'' --critical-usage-percent='90' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::sqldatabase::plugin --mode=cpu --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.Sql/servers//databases/' +--aggregation='maximum' --warning-usage-percent='80'' --critical-usage-percent='90' + +Default aggregation: 'maximum', other are not identified as relevant nor available by Microsoft. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). It is the database name. + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--server> + +Set server name (Required if resource's name is used). + +=item B<--warning-*> B<--critical-*> + +Thresholds where '*' can be: 'usage-percent'. + +=back + +=cut diff --git a/src/cloud/azure/database/sqldatabase/mode/memory.pm b/src/cloud/azure/database/sqldatabase/mode/memory.pm new file mode 100644 index 000000000..9093d52e8 --- /dev/null +++ b/src/cloud/azure/database/sqldatabase/mode/memory.pm @@ -0,0 +1,149 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::database::sqldatabase::mode::memory; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'sqlserver_process_memory_percent' => { + 'output' => 'Memory used percent', + 'label' => 'usage-percent', + 'nlabel' => 'sqldatabase.memory.usage.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' }, + 'server:s' => { name => 'server' } + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group and --server option OR --resource .'); + $self->{output}->option_exit(); + } + my $resource = $self->{option_results}->{resource}; + my $server = $self->{option_results}->{server}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.Sql\/servers\/(.*)\/databases\/(.*)$/) { + $resource_group = $1; + $server = $2; + $resource = $2 . '/databases/' . $3; + } else { + $resource = $server . '/databases/' . $resource; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = 'servers'; + $self->{az_resource_namespace} = 'Microsoft.Sql'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Maximum']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure SQL Database Memory. +Metrics are available with: +- Tier 'DTU based' - Basic, Standard, Premium +- vCore based model - General purpose & Business critical +- HyperScale + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::database::sqldatabase::plugin --mode=memory --custommode=api +--resource= --resource-group= --server= --aggregation='maximum' +--warning-usage-percent='80'' --critical-usage-percent='90' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::database::sqldatabase::plugin --mode=memory --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.Sql/servers//databases/' +--aggregation='maximum' --warning-usage-percent='80'' --critical-usage-percent='90' + +Default aggregation: 'maximum', other are not identified as relevant nor available by Microsoft. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). It is the database name. + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--server> + +Set server name (Required if resource's name is used). + +=item B<--warning-*> B<--critical-*> + +Thresholds where '*' can be: 'usage-percent'. + +=back + +=cut diff --git a/src/cloud/azure/database/sqldatabase/plugin.pm b/src/cloud/azure/database/sqldatabase/plugin.pm index 04489aac8..5f518510c 100644 --- a/src/cloud/azure/database/sqldatabase/plugin.pm +++ b/src/cloud/azure/database/sqldatabase/plugin.pm @@ -32,9 +32,11 @@ sub new { $self->{modes} = { 'app-resources' => 'cloud::azure::database::sqldatabase::mode::appresources', 'connections' => 'cloud::azure::database::sqldatabase::mode::connections', + 'cpu' => 'cloud::azure::database::sqldatabase::mode::cpu', 'discovery' => 'cloud::azure::database::sqldatabase::mode::discovery', 'deadlocks' => 'cloud::azure::database::sqldatabase::mode::deadlocks', 'health' => 'cloud::azure::database::sqldatabase::mode::health', + 'memory' => 'cloud::azure::database::sqldatabase::mode::memory', 'sessions' => 'cloud::azure::database::sqldatabase::mode::sessions', 'storage' => 'cloud::azure::database::sqldatabase::mode::storage', 'workers' => 'cloud::azure::database::sqldatabase::mode::workers' From ed5d4c59587ec4181ef04701749a6dac723ef6da Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 28 Apr 2023 10:08:33 +0200 Subject: [PATCH 407/447] (plugin) cloud::azure::compute::aks - add modes memory, node-state, pod-state and unschedulable-pods (#4369) --- src/cloud/azure/compute/aks/mode/memory.pm | 179 ++++++++++++++++++ src/cloud/azure/compute/aks/mode/nodestate.pm | 131 +++++++++++++ src/cloud/azure/compute/aks/mode/podstate.pm | 148 +++++++++++++++ .../compute/aks/mode/unschedulablepods.pm | 131 +++++++++++++ src/cloud/azure/compute/aks/plugin.pm | 11 +- 5 files changed, 596 insertions(+), 4 deletions(-) create mode 100644 src/cloud/azure/compute/aks/mode/memory.pm create mode 100644 src/cloud/azure/compute/aks/mode/nodestate.pm create mode 100644 src/cloud/azure/compute/aks/mode/podstate.pm create mode 100644 src/cloud/azure/compute/aks/mode/unschedulablepods.pm diff --git a/src/cloud/azure/compute/aks/mode/memory.pm b/src/cloud/azure/compute/aks/mode/memory.pm new file mode 100644 index 000000000..f9619df0c --- /dev/null +++ b/src/cloud/azure/compute/aks/mode/memory.pm @@ -0,0 +1,179 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::compute::aks::mode::memory; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'node_memory_rss_bytes' => { + 'output' => 'memory RSS Usage', + 'label' => 'memory-rss-usage', + 'nlabel' => 'aks.node.memory.rss.bytes', + 'unit' => 'B', + 'min' => '0' + }, + 'node_memory_rss_percentage' => { + 'output' => 'Memory RSS Percent', + 'label' => 'memory-rss-percent', + 'nlabel' => 'aks.node.memory.rss.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '100' + }, + 'node_memory_working_set_bytes' => { + 'output' => 'memory Usage', + 'label' => 'memory-usage', + 'nlabel' => 'aks.node.memory.working.set.bytes', + 'unit' => 'B', + 'min' => '0' + }, + 'node_memory_working_set_percentage' => { + 'output' => 'Memory Percent', + 'label' => 'memory-percent', + 'nlabel' => 'aks.node.memory.working.set.percentage', + 'unit' => '%', + 'min' => '0', + 'max' => '100' + } + + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.ContainerService\/managedClusters\/(.*)$/) { + $resource_group = $1; + $resource = $2; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = 'managedClusters'; + $self->{az_resource_namespace} = 'Microsoft.ContainerService'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Memory usage on Azure Kubernetes Cluster. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=memory --custommode=api +--resource= --resource-group= --warning-memory-percent='90' --critical-memory-percent='95' + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=storage --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.ContainerService/managedClusters/' +--warning-memory-percent='90' --critical-memory-percent='95' + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--warning-memory-usage> + +Warning threshold in Bytes. + +=item B<--critical-memory-usage> + +Critical threshold in Bytes. + +=item B<--warning-memory-percent> + +Warning threshold in percent. + +=item B<--critical-memory-percent> + +Critical threshold in percent. + +=item B<--warning-rss-memory-usage> + +Warning threshold in Bytes. + +=item B<--critical-rss-memory-usage> + +Critical threshold in Bytes. + +=item B<--warning-rss-memory-percent> + +Warning threshold in percent. + +=item B<--critical-rss-memory-percent> + +Critical threshold in percent. + +=back + +=cut diff --git a/src/cloud/azure/compute/aks/mode/nodestate.pm b/src/cloud/azure/compute/aks/mode/nodestate.pm new file mode 100644 index 000000000..cdd372891 --- /dev/null +++ b/src/cloud/azure/compute/aks/mode/nodestate.pm @@ -0,0 +1,131 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::compute::aks::mode::nodestate; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'kube_node_status_condition' => { + 'output' => 'Kube Node State Condition', + 'label' => 'node-state-condition', + 'nlabel' => 'aks.kube.node.status.condition.count', + 'unit' => '', + 'min' => '0' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.ContainerService\/managedClusters\/(.*)$/) { + $resource_group = $1; + $resource = $2; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = 'managedClusters'; + $self->{az_resource_namespace} = 'Microsoft.ContainerService'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Kubernetes number of nodes by state. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=nodestate --custommode=api +--resource= --resource-group= --zeroed --warning-node-state-condition=5 --critical-node-state-condition=10 + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=nodestate --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.ContainerService/managedClusters/' +--zeroed --warning-node-state-condition=5 --critical-node-state-condition=10 + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--warning-node-state-condition> + +Set warning threshold for number of condition nodes. + +=item B<--critical-node-state-condition> + +Set critical threshold for number of condition nodes. + +=back + +=cut diff --git a/src/cloud/azure/compute/aks/mode/podstate.pm b/src/cloud/azure/compute/aks/mode/podstate.pm new file mode 100644 index 000000000..f6ff369a5 --- /dev/null +++ b/src/cloud/azure/compute/aks/mode/podstate.pm @@ -0,0 +1,148 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::compute::aks::mode::podstate; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'kube_pod_status_ready' => { + 'output' => 'Kube Pods State Ready', + 'label' => 'pod-state-ready', + 'nlabel' => 'aks.kube.pod.status.ready.count', + 'unit' => '', + 'min' => '0' + }, + 'kube_pod_status_phase' => { + 'output' => 'Kube Pods State Phase', + 'label' => 'pod-state-phase', + 'nlabel' => 'aks.kube.pod.status.phase.count', + 'unit' => '', + 'min' => '0' + } + + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.ContainerService\/managedClusters\/(.*)$/) { + $resource_group = $1; + $resource = $2; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = 'managedClusters'; + $self->{az_resource_namespace} = 'Microsoft.ContainerService'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Kubernetes number of pods by state. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=pod-state --custommode=api +--resource= --resource-group= --zeroed --warning-pod-state-phase=5 --critical-pod-state-phase=10 + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=pod-state --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.ContainerService/managedClusters/' +--zeroed --warning-pod-state-phase=5 --critical-pod-state-phase=10 + + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--warning-pod-state-ready> + +Set warning threshold for number of Pods State Ready. + +=item B<--critical-pod-state-ready> + +Set critical threshold for number of Pods State Ready. + +=item B<--warning-pod-state-phase> + +Set warning threshold for number of Pods State Phase. + +=item B<--critical-pod-state-phase> + +Set critical threshold for number of Pods State Phase. + +=back + +=cut diff --git a/src/cloud/azure/compute/aks/mode/unschedulablepods.pm b/src/cloud/azure/compute/aks/mode/unschedulablepods.pm new file mode 100644 index 000000000..396d5a9e6 --- /dev/null +++ b/src/cloud/azure/compute/aks/mode/unschedulablepods.pm @@ -0,0 +1,131 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::azure::compute::aks::mode::unschedulablepods; + +use base qw(cloud::azure::custom::mode); + +use strict; +use warnings; + +sub get_metrics_mapping { + my ($self, %options) = @_; + + my $metrics_mapping = { + 'cluster_autoscaler_unschedulable_pods_count' => { + 'output' => 'Cluster Autoscaler Unschedulable Pods', + 'label' => 'unschedulable-pods', + 'nlabel' => 'aks.cluster.autoscaler.unschedulable.pods.count', + 'unit' => '', + 'min' => '0' + } + }; + + return $metrics_mapping; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-metric:s' => { name => 'filter_metric' }, + 'resource:s' => { name => 'resource' }, + 'resource-group:s' => { name => 'resource_group' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify either --resource with --resource-group option or --resource .'); + $self->{output}->option_exit(); + } + + my $resource = $self->{option_results}->{resource}; + my $resource_group = defined($self->{option_results}->{resource_group}) ? $self->{option_results}->{resource_group} : ''; + my $resource_type = $self->{option_results}->{resource_type}; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/(.*)\/providers\/Microsoft\.ContainerService\/managedClusters\/(.*)$/) { + $resource_group = $1; + $resource = $2; + } + + $self->{az_resource} = $resource; + $self->{az_resource_group} = $resource_group; + $self->{az_resource_type} = 'managedClusters'; + $self->{az_resource_namespace} = 'Microsoft.ContainerService'; + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : 'PT5M'; + $self->{az_aggregations} = ['Average']; + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + push @{$self->{az_metrics}}, $metric; + } +} + +1; + +__END__ + +=head1 MODE + +Check Azure Kubernetes Cluster Autoscaler unschedulable pods. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=unschedulable-pods --custommode=api +--resource= --resource-group= --zeroed --warning-unschedulable-pods=5 --critical-unschedulable-pods=10 + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::aks::plugin --mode=unschedulable-pods --custommode=api +--resource='/subscriptions//resourceGroups//providers/Microsoft.ContainerService/managedClusters/' +--zeroed --warning-unschedulable-pods=5 --critical-unschedulable-pods=10 + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--warning-unschedulable-pods> + +Set warning threshold for number of unschedulable pods. + +=item B<--critical-unschedulable-pods> + +Set critical threshold for number of unschedulable pods. + +=back + +=cut diff --git a/src/cloud/azure/compute/aks/plugin.pm b/src/cloud/azure/compute/aks/plugin.pm index f933eb947..27da9b73b 100644 --- a/src/cloud/azure/compute/aks/plugin.pm +++ b/src/cloud/azure/compute/aks/plugin.pm @@ -29,15 +29,18 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '0.1'; $self->{modes} = { 'allocatable-resources' => 'cloud::azure::compute::aks::mode::allocatableresources', 'cpu' => 'cloud::azure::compute::aks::mode::cpu', 'discovery' => 'cloud::azure::compute::aks::mode::discovery', - 'health' => 'cloud::azure::compute::aks::mode::health', + 'health' => 'cloud::azure::compute::aks::mode::health', + 'memory' => 'cloud::azure::compute::aks::mode::memory', + 'node-state' => 'cloud::azure::compute::aks::mode::nodestate', + 'pod-state' => 'cloud::azure::compute::aks::mode::podstate', 'storage' => 'cloud::azure::compute::aks::mode::storage', 'traffic' => 'cloud::azure::compute::aks::mode::traffic', - 'unneeded-nodes' => 'cloud::azure::compute::aks::mode::unneedednodes' + 'unneeded-nodes' => 'cloud::azure::compute::aks::mode::unneedednodes', + 'unschedulable-pods' => 'cloud::azure::compute::aks::mode::unschedulablepods' }; $self->{custom_modes}->{azcli} = 'cloud::azure::custom::azcli'; @@ -49,7 +52,7 @@ sub init { my ($self, %options) = @_; $self->{options}->add_options(arguments => { - 'api-version:s' => { name => 'api_version', default => '2018-01-01' }, + 'api-version:s' => { name => 'api_version', default => '2018-01-01' } }); $self->SUPER::init(%options); From 9b79fc5b352c11cab8d9bc7053895c5b45bed46a Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 28 Apr 2023 10:08:48 +0200 Subject: [PATCH 408/447] (plugin) network::keysight::nvos::restapi - new (#4387) --- .../deb.json | 5 + .../pkg.json | 9 + .../rpm.json | 5 + .../keysight/nvos/restapi/custom/api.pm | 212 +++++++++++++ .../nvos/restapi/mode/dynamicfilters.pm | 193 ++++++++++++ .../keysight/nvos/restapi/mode/hardware.pm | 200 ++++++++++++ .../nvos/restapi/mode/listdynamicfilters.pm | 114 +++++++ .../keysight/nvos/restapi/mode/listports.pm | 124 ++++++++ .../keysight/nvos/restapi/mode/ports.pm | 291 ++++++++++++++++++ .../keysight/nvos/restapi/mode/time.pm | 193 ++++++++++++ .../keysight/nvos/restapi/mode/uptime.pm | 146 +++++++++ src/network/keysight/nvos/restapi/plugin.pm | 54 ++++ 12 files changed, 1546 insertions(+) create mode 100644 packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/deb.json create mode 100644 packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/pkg.json create mode 100644 packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/rpm.json create mode 100644 src/network/keysight/nvos/restapi/custom/api.pm create mode 100644 src/network/keysight/nvos/restapi/mode/dynamicfilters.pm create mode 100644 src/network/keysight/nvos/restapi/mode/hardware.pm create mode 100644 src/network/keysight/nvos/restapi/mode/listdynamicfilters.pm create mode 100644 src/network/keysight/nvos/restapi/mode/listports.pm create mode 100644 src/network/keysight/nvos/restapi/mode/ports.pm create mode 100644 src/network/keysight/nvos/restapi/mode/time.pm create mode 100644 src/network/keysight/nvos/restapi/mode/uptime.pm create mode 100644 src/network/keysight/nvos/restapi/plugin.pm diff --git a/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/deb.json b/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/deb.json new file mode 100644 index 000000000..8133a85e5 --- /dev/null +++ b/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libdatetime-perl" + ] +} diff --git a/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/pkg.json b/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/pkg.json new file mode 100644 index 000000000..a17089c7d --- /dev/null +++ b/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/pkg.json @@ -0,0 +1,9 @@ +{ + "pkg_name": "centreon-plugin-Network-Keysight-Nvos-Restapi", + "pkg_summary": "Centreon Plugin to monitor Keysight NVOS using RestAPI", + "plugin_name": "centreon_keysight_nvos_restapi.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "network/keysight/nvos/restapi/" + ] +} diff --git a/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/rpm.json b/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/rpm.json new file mode 100644 index 000000000..e9dff7552 --- /dev/null +++ b/packaging/centreon-plugin-Network-Keysight-Nvos-Restapi/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(DateTime)" + ] +} diff --git a/src/network/keysight/nvos/restapi/custom/api.pm b/src/network/keysight/nvos/restapi/custom/api.pm new file mode 100644 index 000000000..ec694c9b7 --- /dev/null +++ b/src/network/keysight/nvos/restapi/custom/api.pm @@ -0,0 +1,212 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'api-username:s' => { name => 'api_username' }, + 'api-password:s' => { name => 'api_password' }, + 'hostname:s' => { name => 'hostname' }, + 'port:s' => { name => 'port' }, + 'proto:s' => { name => 'proto' }, + 'timeout:s' => { name => 'timeout' }, + 'unknown-http-status:s' => { name => 'unknown_http_status' }, + 'warning-http-status:s' => { name => 'warning_http_status' }, + 'critical-http-status:s' => { name => 'critical_http_status' } + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl'); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8000; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 50; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : ''; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; + $self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300'; + $self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : ''; + $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : ''; + + if ($self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + if ($self->{api_username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-username option."); + $self->{output}->option_exit(); + } + if ($self->{api_password} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-password option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{credentials} = 1; + $self->{option_results}->{basic} = 1; + $self->{option_results}->{username} = $self->{api_username}; + $self->{option_results}->{password} = $self->{api_password}; +} + +sub settings { + my ($self, %options) = @_; + + return if (defined($self->{settings_done})); + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->set_options(%{$self->{option_results}}); + $self->{settings_done} = 1; +} + +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_port { + my ($self, %options) = @_; + + return $self->{port}; +} + +sub request_api { + my ($self, %options) = @_; + + $self->settings(); + my $content = $self->{http}->request( + method => $options{method}, + url_path => $options{endpoint}, + get_param => $options{get_param}, + query_form_post => $options{query_form_post}, + header => $options{header}, + unknown_status => $self->{unknown_http_status}, + warning_status => $self->{warning_http_status}, + critical_status => $self->{critical_http_status} + ); + + if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) { + $self->{output}->add_option_msg(short_msg => "API error [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +1; + +__END__ + +=head1 NAME + +Keysight NVOS API + +=head1 REST API OPTIONS + +Keysight NVOS API + +=over 8 + +=item B<--hostname> + +Set hostname. + +=item B<--port> + +Port used (Default: 8000) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--api-username> + +API username. + +=item B<--api-password> + +API password. + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/dynamicfilters.pm b/src/network/keysight/nvos/restapi/mode/dynamicfilters.pm new file mode 100644 index 000000000..3c5034cfd --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/dynamicfilters.pm @@ -0,0 +1,193 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::dynamicfilters; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub df_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking dynamic filter '%s'", + $options{instance_value}->{name} + ); +} + +sub prefix_df_output { + my ($self, %options) = @_; + + return sprintf( + "dynamic filter '%s' ", + $options{instance_value}->{name} + ); +} + +sub prefix_traffic_output { + my ($self, %options) = @_; + + return 'traffic '; +} + +sub prefix_packet_output { + my ($self, %options) = @_; + + return 'packets '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'df', type => 3, cb_prefix_output => 'prefix_df_output', cb_long_output => 'df_long_output', + indent_long_output => ' ', message_multiple => 'All dynamic filters are ok', + group => [ + { name => 'traffic', type => 0, cb_prefix_output => 'prefix_traffic_output', skipped_code => { -10 => 1 } }, + { name => 'packet', type => 0, cb_prefix_output => 'prefix_packet_output', skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{traffic} = [ + { label => 'traffic-pass', nlabel => 'dynamic_filter.traffic.pass.bytespersecond', set => { + key_values => [ { name => 'traffic_pass', per_second => 1 } ], + output_template => 'pass: %.2f %s/s', + output_change_bytes => 1, + perfdatas => [ + { template => '%.2f', unit => 'B/s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'traffic-insp', nlabel => 'dynamic_filter.traffic.insp.bytespersecond', set => { + key_values => [ { name => 'traffic_insp', per_second => 1 } ], + output_template => 'insp: %.2f %s/s', + output_change_bytes => 1, + perfdatas => [ + { template => '%.2f', unit => 'B/s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; + + $self->{maps_counters}->{packet} = [ + { label => 'packets-denied', nlabel => 'dynamic_filter.packets.denied.count', set => { + key_values => [ { name => 'packets_denied', diff => 1 } ], + output_template => 'denied: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'packets-pass', nlabel => 'dynamic_filter.packets.pass.count', set => { + key_values => [ { name => 'packets_pass', diff => 1 } ], + output_template => 'pass: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'packets-insp', nlabel => 'dynamic_filter.packets.insp.count', set => { + key_values => [ { name => 'packets_insp', diff => 1 } ], + output_template => 'insp: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api( + method => 'POST', + endpoint => '/api/stats/', + query_form_post => '', + header => ['Content-Type: application/json'], + ); + + $self->{df} = {}; + foreach (@{$result->{stats_snapshot}}) { + next if ($_->{type} ne 'Dynamic Filter'); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $_->{default_name} !~ /$self->{option_results}->{filter_name}/); + + $self->{df}->{ $_->{default_name} } = { + name => $_->{default_name}, + traffic => { + traffic_pass => $_->{df_total_pass_count_bytes}, + traffic_insp => $_->{df_total_insp_count_bytes} + }, + packet => { + packets_denied => $_->{df_total_deny_count_packets}, + packets_insp => $_->{df_total_insp_count_packets}, + packets_pass => $_->{df_total_pass_count_packets} + } + }; + } + + $self->{cache_name} = 'keysight_nvos_' . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . + md5_hex( + (defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : '') . '_' . + (defined($self->{option_results}->{filter_name}) ? $self->{option_results}->{filter_name} : '') + ); +} + +1; + +__END__ + +=head1 MODE + +Check dynamic filters. + +=over 8 + +=item B<--filter-name> + +Filter dynamic filters by name (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'traffic-out-prct', 'traffic-out', 'packets-out', 'packets-dropped', +'packets-pass', 'packets-insp'. + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/hardware.pm b/src/network/keysight/nvos/restapi/mode/hardware.pm new file mode 100644 index 000000000..a533c82ce --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/hardware.pm @@ -0,0 +1,200 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::hardware; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_psu_output { + my ($self, %options) = @_; + + return "power supply '" . $options{instance} . "' "; +} + +sub prefix_temperature_output { + my ($self, %options) = @_; + + return "temperature '" . $options{instance} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'temperatures', type => 1, cb_prefix_output => 'prefix_temperature_output', skipped_code => { -10 => 1 } }, + { name => 'fan', type => 0, skipped_code => { -10 => 1 } }, + { name => 'psus', type => 1, cb_prefix_output => 'prefix_psu_output', message_multiple => 'all power supplies are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{temperatures} = [ + { + label => 'temperature-status', + type => 2, + unknown_default => '%{status} eq "unknown"', + warning_default => '%{status} eq "warn"', + critical_default => '%{status} eq "hot"', + set => { + key_values => [ { name => 'status' }, { name => 'class' } ], + output_template => 'status: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'temperature', nlabel => 'hardware.temperature.celsius', set => { + key_values => [ { name => 'reading' }, { name => 'class' } ], + output_template => 'reading: %s C', + closure_custom_perfdata => sub { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => 'C', + instances => $self->{result_values}->{class}, + value => $self->{result_values}->{reading}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}) + ); + } + } + } + ]; + + $self->{maps_counters}->{fan} = [ + { label => 'fans-failed', nlabel => 'fans.failed.count', set => { + key_values => [ { name => 'failed' } ], + output_template => 'number of failed fans: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{psus} = [ + { label => 'psu-status', type => 2, critical_default => '%{status} eq "bad"', set => { + key_values => [ { name => 'status' }, { name => 'name' } ], + output_template => 'status: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api( + endpoint => '/api/system', + get_param => ['properties=power_module_a,power_module_b,temperature_readings,fan_failure_count'] + ); + if (!defined($result->{power_module_a})) { + $self->{output}->add_option_msg(short_msg => "Cannot find hardware informations"); + $self->{output}->option_exit(); + } + + $self->{temperatures} = {}; + foreach (@{$result->{temperature_readings}}) { + $self->{temperatures}->{ $_->{temperature_sensor}->{id}->{module_class} } = { + class => $_->{temperature_sensor}->{id}->{module_class}, + status => lc($_->{temperature_status}), + reading => $_->{temperature} + }; + } + + # -1 means: unsupported + if ($result->{fan_failure_count} > -1) { + $self->{fan} = { failed => $result->{fan_failure_count} }; + } + + $self->{psus} = { + power_module_a => { + name => 'power_module_a', + status => lc($result->{power_module_a}->{power_supply_status}) + }, + power_module_b => { + name => 'power_module_b', + status => lc($result->{power_module_b}->{power_supply_status}) + } + }; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--unknown-temperature-status> + +Set unknown threshold for status (Default : '%{status} eq "unknown"'). +Can used special variables like: %{status}, %{class} + +=item B<--warning-temperature-status> + +Set warning threshold for status (Default : '%{status} eq "warn"'). +Can used special variables like: %{status}, %{class} + +=item B<--critical-temperature-status> + +Set critical threshold for status (Default: '%{status} eq "hot"'); +Can used special variables like: %{status}, %{class} + +=item B<--unknown-psu-status> + +Set unknown threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--warning-psu-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} eq "bad"'); +Can used special variables like: %{status}, %{name} + +=item B<--warning-*> B<--critical-*> + +Thresholds. Can be: +'temperature', 'fans-failed'. + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/listdynamicfilters.pm b/src/network/keysight/nvos/restapi/mode/listdynamicfilters.pm new file mode 100644 index 000000000..ce27dc665 --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/listdynamicfilters.pm @@ -0,0 +1,114 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::listdynamicfilters; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $df = $options{custom}->request_api( + method => 'POST', + endpoint => '/api/stats/', + query_form_post => '', + header => ['Content-Type: application/json'], + ); + + my $results = []; + foreach (@{$df->{stats_snapshot}}) { + next if ($_->{type} ne 'Dynamic Filter'); + + push @$results, { + name => $_->{default_name} + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->output_add( + long_msg => sprintf( + '[name: %s]', + $_->{name} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List dynamic filters:' + ); + + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'type', 'folder', 'application', 'ctm', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->add_disco_entry(%$_); + } +} + +1; + +__END__ + +=head1 MODE + +List dynamic filters. + +=over 8 + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/listports.pm b/src/network/keysight/nvos/restapi/mode/listports.pm new file mode 100644 index 000000000..b209c9379 --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/listports.pm @@ -0,0 +1,124 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::listports; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $ports = $options{custom}->request_api( + method => 'POST', + endpoint => '/api/stats/', + query_form_post => '', + header => ['Content-Type: application/json'], + ); + + my $results = []; + foreach (@{$ports->{stats_snapshot}}) { + next if ($_->{type} ne 'Port'); + + my $info = $options{custom}->request_api( + method => 'GET', + endpoint => '/api/ports/' . $_->{default_name}, + get_param => ['properties=enabled,license_status,link_status'] + ); + + push @$results, { + name => $_->{default_name}, + adminStatus => $info->{enabled} =~ /true|1/i ? 'enabled' : 'disabled', + operationalStatus => $info->{link_status}->{link_up} =~ /true|1/i ? 'up' : 'down' + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->output_add( + long_msg => sprintf( + '[name: %s][adminStatus: %s][operationalStatus: %s]', + $_->{name}, + $_->{adminStatus}, + $_->{operationalStatus} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List ports:' + ); + + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'type', 'folder', 'application', 'ctm', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach (@$results) { + $self->{output}->add_disco_entry(%$_); + } +} + +1; + +__END__ + +=head1 MODE + +List ports. + +=over 8 + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/ports.pm b/src/network/keysight/nvos/restapi/mode/ports.pm new file mode 100644 index 000000000..b85b3f691 --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/ports.pm @@ -0,0 +1,291 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::ports; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_link_output { + my ($self, %options) = @_; + + return sprintf( + "link operational status: %s [admin: %s]", + $self->{result_values}->{operationalStatus}, + $self->{result_values}->{adminStatus} + ); +} + +sub port_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking port '%s'", + $options{instance_value}->{name} + ); +} + +sub prefix_port_output { + my ($self, %options) = @_; + + return sprintf( + "port '%s' ", + $options{instance_value}->{name} + ); +} + +sub prefix_traffic_output { + my ($self, %options) = @_; + + return 'traffic out: '; +} + +sub prefix_packet_output { + my ($self, %options) = @_; + + return 'packets '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'ports', type => 3, cb_prefix_output => 'prefix_port_output', cb_long_output => 'port_long_output', + indent_long_output => ' ', message_multiple => 'All ports are ok', + group => [ + { name => 'license', type => 0, skipped_code => { -10 => 1 } }, + { name => 'link', type => 0, skipped_code => { -10 => 1 } }, + { name => 'traffic', type => 0, cb_prefix_output => 'prefix_traffic_output', skipped_code => { -10 => 1 } }, + { name => 'packet', type => 0, cb_prefix_output => 'prefix_packet_output', skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{license} = [ + { + label => 'license-status', + type => 2, + warning_default => '%{status} =~ /invalid_software_version/', + set => { + key_values => [ + { name => 'status' }, { name => 'name' } + ], + output_template => 'license status: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{link} = [ + { + label => 'link-status', + type => 2, + critical_default => '%{adminStatus} eq "enabled" and %{operationalStatus} ne "up"', + set => { + key_values => [ + { name => 'adminStatus' }, { name => 'operationalStatus' } , { name => 'name' } + ], + closure_custom_output => $self->can('custom_link_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{traffic} = [ + { label => 'traffic-out-prct', nlabel => 'port.traffic.out.percentage', set => { + key_values => [ { name => 'traffic_out_util' } ], + output_template => '%.2f%%', + perfdatas => [ + { template => '%.2f', unit => '%', min => 0, max => 100, label_extra_instance => 1 } + ] + } + }, + { label => 'traffic-out', nlabel => 'port.traffic.out.bytespersecond', set => { + key_values => [ { name => 'traffic_out', per_second => 1 } ], + output_template => '%.2f %s/s', + output_change_bytes => 1, + perfdatas => [ + { template => '%.2f', unit => 'B/s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; + + $self->{maps_counters}->{packet} = [ + { label => 'packets-out', nlabel => 'port.packets.out.count', set => { + key_values => [ { name => 'packets_out', diff => 1 } ], + output_template => 'out: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'packets-dropped', nlabel => 'port.packets.dropped.count', set => { + key_values => [ { name => 'packets_dropped', diff => 1 } ], + output_template => 'dropped: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'packets-pass', nlabel => 'port.packets.pass.count', set => { + key_values => [ { name => 'packets_pass', diff => 1 } ], + output_template => 'pass: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'packets-insp', nlabel => 'port.packets.insp.count', set => { + key_values => [ { name => 'packets_insp', diff => 1 } ], + output_template => 'insp: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api( + method => 'POST', + endpoint => '/api/stats/', + query_form_post => '', + header => ['Content-Type: application/json'], + ); + + $self->{ports} = {}; + foreach (@{$result->{stats_snapshot}}) { + next if ($_->{type} ne 'Port'); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $_->{default_name} !~ /$self->{option_results}->{filter_name}/); + + my $info = $options{custom}->request_api( + method => 'GET', + endpoint => '/api/ports/' . $_->{default_name}, + get_param => ['properties=enabled,license_status,link_status'] + ); + + $self->{ports}->{ $_->{default_name} } = { + name => $_->{default_name}, + license => { + name => $_->{default_name}, + status => lc($info->{license_status}), + }, + link => { + name => $_->{default_name}, + adminStatus => $info->{enabled} =~ /true|1/i ? 'enabled' : 'disabled', + operationalStatus => $info->{link_status}->{link_up} =~ /true|1/i ? 'up' : 'down' + }, + traffic => { + traffic_out => $_->{tp_total_tx_count_bytes}, + traffic_out_util => $_->{tp_current_tx_utilization} + }, + packet => { + packets_out => $_->{tp_total_tx_count_packets}, + packets_dropped => $_->{tp_total_drop_count_packets}, + packets_insp => $_->{tp_total_insp_count_packets}, + packets_pass => $_->{tp_total_pass_count_packets} + } + }; + } + + $self->{cache_name} = 'keysight_nvos_' . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . + md5_hex( + (defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : '') . '_' . + (defined($self->{option_results}->{filter_name}) ? $self->{option_results}->{filter_name} : '') + ); +} + +1; + +__END__ + +=head1 MODE + +Check ports. + +=over 8 + +=item B<--filter-name> + +Filter ports by name (can be a regexp). + +=item B<--unknown-license-status> + +Set unknown threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--warning-license-status> + +Set warning threshold for status (Default: '%{status} =~ /invalid_software_version/'). +Can used special variables like: %{status}, %{name} + +=item B<--critical-license-status> + +Set critical threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--unknown-link-status> + +Set unknown threshold for status. +Can used special variables like: %{adminStatus}, %{operationalStatus}, %{name} + +=item B<--warning-link-status> + +Set warning threshold for status. +Can used special variables like: %{adminStatus}, %{operationalStatus}, %{name} + +=item B<--critical-link-status> + +Set critical threshold for status (Default: '%{adminStatus} eq "enabled" and %{operationalStatus} ne "up"'). +Can used special variables like: %{adminStatus}, %{operationalStatus}, %{name} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'traffic-out-prct', 'traffic-out', 'packets-out', 'packets-dropped', +'packets-pass', 'packets-insp'. + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/time.pm b/src/network/keysight/nvos/restapi/mode/time.pm new file mode 100644 index 000000000..44c077e9e --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/time.pm @@ -0,0 +1,193 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::time; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use DateTime; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_usage_output { + my ($self, %options) = @_; + + return sprintf( + 'time offset %d second(s): %s', + $self->{result_values}->{offset}, + $self->{result_values}->{date} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'offset', type => 0 } + ]; + + $self->{maps_counters}->{offset} = [ + { + label => 'ntp-status', + type => 2, + critical_default => '%{status} !~ /in_reach|in_sync/i', + set => { + key_values => [ { name => 'status' } ], + output_template => 'ntp status: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'offset', nlabel => 'time.offset.seconds', set => { + key_values => [ { name => 'offset' }, { name => 'date' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { template => '%d', unit => 's' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'ntp-hostname:s' => { name => 'ntp_hostname' }, + 'ntp-port:s' => { name => 'ntp_port', default => 123 }, + 'timezone:s' => { name => 'timezone' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (defined($self->{option_results}->{ntp_hostname})) { + centreon::plugins::misc::mymodule_load( + output => $self->{output}, module => 'Net::NTP', + error_msg => "Cannot load module 'Net::NTP'." + ); + } +} + +sub get_target_time { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api( + endpoint => '/api/system', + get_param => ['properties=system_time,ntp_server_status'] + ); + if (!defined($result->{system_time})) { + $self->{output}->add_option_msg(short_msg => "Cannot find time informations"); + $self->{output}->option_exit(); + } + + my $tz = {}; + if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { + $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + } + + my $dt = DateTime->from_epoch(epoch => $result->{system_time} / 1000, %$tz); + + return ($dt->epoch(), $dt->iso8601(), $result->{ntp_server_status}); +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($distant_time, $remote_date, $ntp_status) = $self->get_target_time(%options); + + my $ref_time; + if (defined($self->{option_results}->{ntp_hostname}) && $self->{option_results}->{ntp_hostname} ne '') { + my %ntp; + + eval { + %ntp = Net::NTP::get_ntp_response($self->{option_results}->{ntp_hostname}, $self->{option_results}->{ntp_port}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Couldn't connect to ntp server: " . $@); + $self->{output}->option_exit(); + } + + $ref_time = $ntp{'Transmit Timestamp'}; + } else { + $ref_time = time(); + } + + my $offset = $distant_time - $ref_time; + $self->{offset} = { + status => lc($ntp_status), + offset => sprintf('%d', $offset), + date => $remote_date + }; +} + +1; + +__END__ + +=head1 MODE + +Check time offset of server with ntp server. Use local time if ntp-host option is not set. + +=over 8 + +=item B<--unknown-ntp-status> + +=item B<--warning-ntp-status> + +=item B<--critical-ntp-status> + +Set thresholds for status (Default critical: '%{status} !~ /in_reach|in_sync/i') + + +Can used special variables like: %{status} + +=item B<--warning-offset> + +Time offset warning threshold (in seconds). + +=item B<--critical-offset> + +Time offset critical Threshold (in seconds). + +=item B<--ntp-hostname> + +Set the ntp hostname (if not set, localtime is used). + +=item B<--ntp-port> + +Set the ntp port (Default: 123). + +=item B<--timezone> + +Override the timezone of distant equipment. +Can use format: 'Europe/London' or '+0100'. + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/mode/uptime.pm b/src/network/keysight/nvos/restapi/mode/uptime.pm new file mode 100644 index 000000000..1a07d8e90 --- /dev/null +++ b/src/network/keysight/nvos/restapi/mode/uptime.pm @@ -0,0 +1,146 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::mode::uptime; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use POSIX; +use centreon::plugins::misc; + +my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 }; +my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' }; + +sub custom_uptime_output { + my ($self, %options) = @_; + + return sprintf( + 'System uptime is: %s', + centreon::plugins::misc::change_seconds(value => $self->{result_values}->{uptime}, start => 'd') + ); +} + +sub custom_uptime_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => 'system.uptime.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} }, + value => floor($self->{result_values}->{uptime} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); +} + +sub custom_uptime_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => floor($self->{result_values}->{uptime} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }, + { label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' } + ] + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'uptime', set => { + key_values => [ { name => 'uptime' } ], + closure_custom_output => $self->can('custom_uptime_output'), + closure_custom_perfdata => $self->can('custom_uptime_perfdata'), + closure_custom_threshold_check => $self->can('custom_uptime_threshold') + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'unit:s' => { name => 'unit', default => 's' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) { + $self->{option_results}->{unit} = 's'; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api( + endpoint => '/api/system', + get_param => ['properties=ready_time'] + ); + if (!defined($result->{ready_time})) { + $self->{output}->add_option_msg(short_msg => "Cannot find uptime information"); + $self->{output}->option_exit(); + } + + $self->{global} = { uptime => time() - ($result->{ready_time} / 1000) }; +} + +1; + +__END__ + +=head1 MODE + +Check system uptime. + +=over 8 + +=item B<--warning-uptime> + +Threshold warning. + +=item B<--critical-uptime> + +Threshold critical. + +=item B<--unit> + +Select the unit for performance data and thresholds. May be 's' for seconds, 'm' for minutes, +'h' for hours, 'd' for days, 'w' for weeks. Default is seconds + +=back + +=cut diff --git a/src/network/keysight/nvos/restapi/plugin.pm b/src/network/keysight/nvos/restapi/plugin.pm new file mode 100644 index 000000000..47e6b70b5 --- /dev/null +++ b/src/network/keysight/nvos/restapi/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::keysight::nvos::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'dynamic-filters' => 'network::keysight::nvos::restapi::mode::dynamicfilters', + 'hardware' => 'network::keysight::nvos::restapi::mode::hardware', + 'list-dynamic-filters' => 'network::keysight::nvos::restapi::mode::listdynamicfilters', + 'list-ports' => 'network::keysight::nvos::restapi::mode::listports', + 'ports' => 'network::keysight::nvos::restapi::mode::ports', + 'time' => 'network::keysight::nvos::restapi::mode::time', + 'uptime' => 'network::keysight::nvos::restapi::mode::uptime' + }; + + $self->{custom_modes}->{api} = 'network::keysight::nvos::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Keysight Network Visibility Operating System (NVOS) using rest API. + +=cut From 8e41e054ae6258db309efb884304204ec85b8e6a Mon Sep 17 00:00:00 2001 From: Thibault S <48209914+thibaults-centreon@users.noreply.github.com> Date: Fri, 28 Apr 2023 10:46:30 +0200 Subject: [PATCH 409/447] apps::monitoring::kadiska::plugin - fix metric format (#4385) --- src/apps/monitoring/kadiska/mode/watcherstatistics.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/monitoring/kadiska/mode/watcherstatistics.pm b/src/apps/monitoring/kadiska/mode/watcherstatistics.pm index 962a3539e..860c7d52a 100644 --- a/src/apps/monitoring/kadiska/mode/watcherstatistics.pm +++ b/src/apps/monitoring/kadiska/mode/watcherstatistics.pm @@ -33,7 +33,7 @@ sub custom_usage_perfdata_ms { nlabel => $self->{nlabel}, unit => 'ms', instances => [ $self->{result_values}->{watcher_name}, $self->{result_values}->{site_name}, $self->{result_values}->{gateway_name} ], - value => sprintf('%s', $self->{result_values}->{ $self->{key_values}->[0]->{name} } ), + value => sprintf('%.2f', $self->{result_values}->{ $self->{key_values}->[0]->{name} } ), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), min => 0 @@ -46,7 +46,7 @@ sub custom_usage_perfdata { $self->{output}->perfdata_add( nlabel => $self->{nlabel}, instances => [ $self->{result_values}->{watcher_name}, $self->{result_values}->{site_name}, $self->{result_values}->{gateway_name} ], - value => sprintf('%s', $self->{result_values}->{ $self->{key_values}->[0]->{name} } ), + value => sprintf('%.2f', $self->{result_values}->{ $self->{key_values}->[0]->{name} } ), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), min => 0 From 9b3b6d33e10a64421b0cfb2fbc453aa38e5eaea4 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Thu, 11 May 2023 07:01:13 +0200 Subject: [PATCH 410/447] fix(packaging): manage custom instructions for debian packaging (#4398) * fix(packaging): manage custom instructions for debian packaging * fix(packaging): manage custom instructions for debian packaging * fix(packaging): manage custom instructions for debian packaging * fix(packaging): manage custom instructions for debian packaging * fix(packaging): manage custom instructions for debian packaging * fix(packaging): manage custom instructions for debian packaging * breaks * fix * fix * fix * fix --- .github/packaging/debian/control.body.template | 2 +- .github/scripts/plugin-packaging-deb.sh | 8 +++++++- .../deb.json | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/packaging/debian/control.body.template b/.github/packaging/debian/control.body.template index 4a9238ec0..340a0939e 100644 --- a/.github/packaging/debian/control.body.template +++ b/.github/packaging/debian/control.body.template @@ -1,7 +1,7 @@ Package: @NAME@ Architecture: all -Description: @SUMMARY@ +Description: @SUMMARY@@CUSTOM_PKG_DATA@ Depends: ${shlibs:Depends}, ${misc:Depends}, diff --git a/.github/scripts/plugin-packaging-deb.sh b/.github/scripts/plugin-packaging-deb.sh index 2d95f0049..1ae6eff80 100755 --- a/.github/scripts/plugin-packaging-deb.sh +++ b/.github/scripts/plugin-packaging-deb.sh @@ -33,8 +33,14 @@ for PLUGIN in $PLUGINS; do pkg_summary=$(echo "${pkg_values[0]}") plugin_name=$(echo "${pkg_values[1]}") deb_dependencies=$(cat "packaging/$PACKAGE_PATH/deb.json" | jq -r '.dependencies | join(",\\n ")') + deb_custom_pkg_data=$(cat "packaging/$PACKAGE_PATH/deb.json" | jq -r '("\\n" + .custom_pkg_data) // ""') - sed -e "s/@NAME@/$PLUGIN_NAME_LOWER/g" -e "s/@SUMMARY@/$pkg_summary/g" -e "s/@REQUIRES@/$deb_dependencies/g" < centreon-plugins/debian/control.body.template >> centreon-plugins/debian/control + sed -e "s/@NAME@/$PLUGIN_NAME_LOWER/g" \ + -e "s/@SUMMARY@/$pkg_summary/g" \ + -e "s/@REQUIRES@/$deb_dependencies/g" \ + -e "s/@CUSTOM_PKG_DATA@/$deb_custom_pkg_data/g" \ + < centreon-plugins/debian/control.body.template \ + >> centreon-plugins/debian/control # .install file sed -e "s/@DIR@/$PLUGIN/g" -e "s/@NAME@/$plugin_name/g" < centreon-plugins/debian/plugin.install.template >> centreon-plugins/debian/$PLUGIN_NAME_LOWER.install diff --git a/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json b/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json index 9757fe112..0e63cdedf 100644 --- a/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json +++ b/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json @@ -1,4 +1,5 @@ { "dependencies": [ - ] + ], + "custom_pkg_data": "Provides: centreon-plugin-Network-Cisco-Ssms-Restapi\\nReplaces: centreon-plugin-Network-Cisco-Ssms-Restapi\\nConflicts: centreon-plugin-Network-Cisco-Ssms-Restapi" } From e6e2179f084a7a9a4a688ff4e1b91fa1f7867702 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Thu, 11 May 2023 17:29:31 +0200 Subject: [PATCH 411/447] fix(packaging): remove centreon-plugin-Network-Cisco-Ssms-Restapi (#4413) --- .../deb.json | 2 +- .../centreon-plugin-Network-Cisco-Ssms-Restapi/deb.json | 4 ---- .../centreon-plugin-Network-Cisco-Ssms-Restapi/pkg.json | 9 --------- .../centreon-plugin-Network-Cisco-Ssms-Restapi/rpm.json | 4 ---- 4 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/deb.json delete mode 100644 packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/pkg.json delete mode 100644 packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/rpm.json diff --git a/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json b/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json index 0e63cdedf..ea676ec3b 100644 --- a/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json +++ b/packaging/centreon-plugin-Applications-Cisco-Ssms-Restapi/deb.json @@ -1,5 +1,5 @@ { "dependencies": [ ], - "custom_pkg_data": "Provides: centreon-plugin-Network-Cisco-Ssms-Restapi\\nReplaces: centreon-plugin-Network-Cisco-Ssms-Restapi\\nConflicts: centreon-plugin-Network-Cisco-Ssms-Restapi" + "custom_pkg_data": "Provides: centreon-plugin-network-cisco-ssms-restapi\\nReplaces: centreon-plugin-network-cisco-ssms-restapi\\nConflicts: centreon-plugin-network-cisco-ssms-restapi" } diff --git a/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/deb.json b/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/deb.json deleted file mode 100644 index 9757fe112..000000000 --- a/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/deb.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "dependencies": [ - ] -} diff --git a/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/pkg.json b/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/pkg.json deleted file mode 100644 index 499dfb523..000000000 --- a/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/pkg.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "pkg_name": "centreon-plugin-Network-Cisco-Ssms-Restapi", - "pkg_summary": "Centreon Plugin to monitor Cisco Smart Software Manager Satellite using RestAPI", - "plugin_name": "centreon_cisco_ssms_restapi.pl", - "files": [ - "centreon/plugins/script_custom.pm", - "apps/cisco/ssms/restapi/" - ] -} diff --git a/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/rpm.json b/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/rpm.json deleted file mode 100644 index 9757fe112..000000000 --- a/packaging/centreon-plugin-Network-Cisco-Ssms-Restapi/rpm.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "dependencies": [ - ] -} From 2c290d16e4d1c7e3bda2768eb2f0298197dc55fd Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 09:52:53 +0200 Subject: [PATCH 412/447] chore(ci): remove unnecessary files --- connectors/vmware/Jenkinsfile | 69 ------ connectors/vmware/LICENSE | 202 ------------------ connectors/vmware/ci/debian/control | 21 -- connectors/vmware/ci/debian/copyright | 29 --- connectors/vmware/ci/debian/install | 4 - connectors/vmware/ci/debian/postinst | 22 -- connectors/vmware/ci/debian/rules | 6 - connectors/vmware/ci/debian/source/format | 1 - .../vmware/ci/scripts/vmware-deb-package.sh | 49 ----- .../ci/scripts/vmware-deliver-deb-package.sh | 10 - 10 files changed, 413 deletions(-) delete mode 100644 connectors/vmware/Jenkinsfile delete mode 100644 connectors/vmware/LICENSE delete mode 100644 connectors/vmware/ci/debian/control delete mode 100644 connectors/vmware/ci/debian/copyright delete mode 100644 connectors/vmware/ci/debian/install delete mode 100644 connectors/vmware/ci/debian/postinst delete mode 100755 connectors/vmware/ci/debian/rules delete mode 100644 connectors/vmware/ci/debian/source/format delete mode 100755 connectors/vmware/ci/scripts/vmware-deb-package.sh delete mode 100755 connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh diff --git a/connectors/vmware/Jenkinsfile b/connectors/vmware/Jenkinsfile deleted file mode 100644 index 1f050d4c7..000000000 --- a/connectors/vmware/Jenkinsfile +++ /dev/null @@ -1,69 +0,0 @@ -stage('Source') { - node { - sh 'setup_centreon_build.sh' - dir('centreon-vmware') { - checkout scm - } - sh './centreon-build/jobs/vmware/vmware-source.sh' - source = readProperties file: 'source.properties' - env.VERSION = "${source.VERSION}" - env.RELEASE = "${source.RELEASE}" - } -} - -try { - stage('Package') { - parallel 'centos7': { - node { - sh 'setup_centreon_build.sh' - sh './centreon-build/jobs/vmware/vmware-package.sh centos7' - archiveArtifacts artifacts: 'rpms-centos7.tar.gz' - stash name: "rpms-centos7", includes: 'output/noarch/*.rpm' - sh 'rm -rf output' - } - }, - 'alma8': { - node { - sh 'setup_centreon_build.sh' - sh './centreon-build/jobs/vmware/vmware-package.sh alma8' - archiveArtifacts artifacts: 'rpms-alma8.tar.gz' - stash name: "rpms-alma8", includes: 'output/noarch/*.rpm' - sh 'rm -rf output' - } - }, - 'Debian bullseye packaging and signing': { - node { - dir('centreon-vmware') { - checkout scm - } - sh 'docker run -i --entrypoint "/src/centreon-vmware/ci/scripts/vmware-deb-package.sh" -w "/src" -v "$PWD:/src" -e "DISTRIB=bullseye" -e "VERSION=$VERSION" -e "RELEASE=$RELEASE" registry.centreon.com/centreon-debian11-dependencies:22.04' - stash name: 'Debian11', includes: '*.deb' - archiveArtifacts artifacts: "*" - } - } - if ((currentBuild.result ?: 'SUCCESS') != 'SUCCESS') { - error('Package stage failure.'); - } - } - stage('Delivery') { - node { - sh 'setup_centreon_build.sh' - unstash "rpms-centos7" - unstash "rpms-alma8" - sh './centreon-build/jobs/vmware/vmware-delivery.sh' - withCredentials([usernamePassword(credentialsId: 'nexus-credentials', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { - checkout scm - unstash "Debian11" - sh '''for i in $(echo *.deb) - do - curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD -H "Content-Type: multipart/form-data" --data-binary "@./$i" https://apt.centreon.com/repository/22.04-unstable/ - done - ''' - } - } - } -} catch(e) { - if (env.BRANCH_NAME == 'master') { - slackSend channel: "#monitoring-metrology", color: "#F30031", message: "*FAILURE*: `CENTREON VMWARE` <${env.BUILD_URL}|build #${env.BUILD_NUMBER}> on branch ${env.BRANCH_NAME}\n*COMMIT*: by ${source.COMMITTER}\n*INFO*: ${e}" - } -} diff --git a/connectors/vmware/LICENSE b/connectors/vmware/LICENSE deleted file mode 100644 index 9ec83b986..000000000 --- a/connectors/vmware/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright (C) 2008-2022 CENTREON - contact@centreon.com - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/connectors/vmware/ci/debian/control b/connectors/vmware/ci/debian/control deleted file mode 100644 index 1a14ed6cb..000000000 --- a/connectors/vmware/ci/debian/control +++ /dev/null @@ -1,21 +0,0 @@ -Source: centreon-plugin-virtualization-vmware-daemon -Section: net -Priority: optional -Maintainer: Centreon -Build-Depends: debhelper-compat (= 12) -Standards-Version: 4.5.0 -Homepage: https://www.centreon.com - -Package: centreon-plugin-virtualization-vmware-daemon -Architecture: all -Depends: ${misc:Depends}, - ${shlibs:Depends}, - libio-socket-inet6-perl, - libnet-curl-perl, - libjson-xs-perl, - liblwp-protocol-https-perl, - libtext-template-perl, - libzmq-constants-perl, - zmq-libzmq4-perl, - perl-vmware-vsphere -Description: Perl daemon to monitor VSphere Infrastructure diff --git a/connectors/vmware/ci/debian/copyright b/connectors/vmware/ci/debian/copyright deleted file mode 100644 index 8a4623a97..000000000 --- a/connectors/vmware/ci/debian/copyright +++ /dev/null @@ -1,29 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: centreon-plugin-virtualization-vmware-daemon -Upstream-Contact: Centreon -Source: https://www.centreon.com - -Files: * -Copyright: 2022 Centreon -License: Apache-2.0 - -Files: debian/* -Copyright: 2022 Centreon -License: Apache-2.0 - -License: Apache-2.0 - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - . - https://www.apache.org/licenses/LICENSE-2.0 - . - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - . - On Debian systems, the complete text of the Apache version 2.0 license - can be found in "/usr/share/common-licenses/Apache-2.0". - diff --git a/connectors/vmware/ci/debian/install b/connectors/vmware/ci/debian/install deleted file mode 100644 index d1b8c1853..000000000 --- a/connectors/vmware/ci/debian/install +++ /dev/null @@ -1,4 +0,0 @@ -centreon_vmware.pl usr/bin -contrib/debian/centreon_vmware-systemd lib/systemd/system -contrib/config/centreon_vmware-conf.pm etc/centreon -centreon/* usr/share/perl5/centreon diff --git a/connectors/vmware/ci/debian/postinst b/connectors/vmware/ci/debian/postinst deleted file mode 100644 index 1080a2ed7..000000000 --- a/connectors/vmware/ci/debian/postinst +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -if [ "$1" = "configure" ] ; then - - if [ -e "/lib/systemd/system/centreon_vmware-systemd" ]; then - mv /lib/systemd/system/centreon_vmware-systemd /lib/systemd/system/centreon_vmware.service - fi - - if [ -e "/etc/centreon/centreon_vmware-conf.pm" ]; then - mv /etc/centreon/centreon_vmware-conf.pm /etc/centreon/centreon_vmware.pm - fi - - if [ "$(getent passwd centreon)" ]; then - chown centreon:centreon /etc/centreon/centreon_vmware.pm - fi - - systemctl daemon-reload - systemctl enable centreon_vmware.service - systemctl restart centreon_vmware.service - -fi -exit 0 \ No newline at end of file diff --git a/connectors/vmware/ci/debian/rules b/connectors/vmware/ci/debian/rules deleted file mode 100755 index d8309f67d..000000000 --- a/connectors/vmware/ci/debian/rules +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/make -f - -export DEB_BUILD_MAINT_OPTIONS = hardening=+all - -%: - dh $@ diff --git a/connectors/vmware/ci/debian/source/format b/connectors/vmware/ci/debian/source/format deleted file mode 100644 index 163aaf8d8..000000000 --- a/connectors/vmware/ci/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/connectors/vmware/ci/scripts/vmware-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deb-package.sh deleted file mode 100755 index 9926564b3..000000000 --- a/connectors/vmware/ci/scripts/vmware-deb-package.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -set -ex - -if [ -z "$VERSION" -o -z "$RELEASE" -o -z "$DISTRIB" ] ; then - echo "You need to specify VERSION / RELEASE / DISTRIB variables" - exit 1 -fi - -echo "################################################## PACKAGING COLLECT ##################################################" - -AUTHOR="Centreon" -AUTHOR_EMAIL="contact@centreon.com" - -if [ -d /build ]; then - rm -rf /build -fi -mkdir -p /build -cd /build - -# fix version to debian format accept -VERSION="$(echo $VERSION | sed 's/-/./g')" - -# Make perl-VMware-vSphere dependecy -wget -O - https://gitlab.labexposed.com/centreon-lab/perl-VMware-vSphere/-/raw/master/storage/VMware-vSphere-Perl-SDK-7.0.0-17698549.x86_64.tar.gz | tar zxvf - -mv vmware-vsphere-cli-distrib vmware-vsphere-cli -tar czvf vmware-vsphere-cli-7.0.0.tar.gz vmware-vsphere-cli -cd vmware-vsphere-cli -git clone https://github.com/centreon-lab/perl-vmware-debian debian -debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "7.0.0" -y -r "${DISTRIB}" -debuild-pbuilder -cd .. - -cp -rv /src/centreon-vmware /build/ -mv -v /build/centreon-vmware /build/centreon-plugin-virtualization-vmware-daemon -(cd /build && tar czvpf - centreon-plugin-virtualization-vmware-daemon) | dd of=centreon-plugin-virtualization-vmware-daemon-$VERSION.tar.gz -cp -rv /src/centreon-vmware/ci/debian /build/centreon-plugin-virtualization-vmware-daemon/ - -cd /build/centreon-plugin-virtualization-vmware-daemon -debmake -f "${AUTHOR}" -e "${AUTHOR_EMAIL}" -u "$VERSION" -y -r "$DISTRIB" -debuild-pbuilder -cd /build - -if [ -d "$DISTRIB" ] ; then - rm -rf "$DISTRIB" -fi -mkdir $DISTRIB -mv /build/*.deb $DISTRIB/ -ls -lart /build/$DISTRIB -mv /build/$DISTRIB/*.deb /src diff --git a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh b/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh deleted file mode 100755 index 2017d59cd..000000000 --- a/connectors/vmware/ci/scripts/vmware-deliver-deb-package.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -ex - -BULLSEYEPACKAGES=`echo *.deb` - -for i in $BULLSEYEPACKAGES -do - echo "Sending $i" - curl -u \'$1:$2\' -H "Content-Type: multipart/form-data" --data-binary \"@/$i\" "https://apt.centreon.com/repository/22.04" -done From b5bd43e74fc15df55e13f58659ad041e0d1e3645 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 13:32:38 +0200 Subject: [PATCH 413/447] chore(ci): add workflow to package centreon vmware connector --- .../docker/Dockerfile.packaging-plugins-alma8 | 10 +- .../docker/Dockerfile.packaging-plugins-alma9 | 10 +- .../Dockerfile.packaging-plugins-bullseye | 13 +- .../Dockerfile.packaging-plugins-centos7 | 10 +- .github/workflows/connector-vmware.yml | 57 +++++++ .github/workflows/get-environment.yml | 12 +- .github/workflows/package.yml | 139 ++++++++++++++++++ ...n-plugin-virtualization-vmware-daemon.yaml | 93 ++++++++++++ .../packaging/debian/centreon_vmware-default | 9 +- 9 files changed, 335 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/connector-vmware.yml create mode 100644 .github/workflows/package.yml create mode 100644 connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml diff --git a/.github/docker/Dockerfile.packaging-plugins-alma8 b/.github/docker/Dockerfile.packaging-plugins-alma8 index 5e162edb8..19fcc1b24 100644 --- a/.github/docker/Dockerfile.packaging-plugins-alma8 +++ b/.github/docker/Dockerfile.packaging-plugins-alma8 @@ -2,9 +2,15 @@ ARG REGISTRY_URL FROM ${REGISTRY_URL}/almalinux:8 -RUN <> $GITHUB_OUTPUT - VERSION=`date '+%Y%m%d'` + if [[ "${{ inputs.version_file }}" == "" ]]; then + VERSION=$(date '+%Y%m%d') + else + VERSION=$(grep VERSION ${{ inputs.version_file }} | cut -d "'" -f 2) + fi echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT - RELEASE=`date '+%H%M%S'` + RELEASE=$(date '+%H%M%S') echo "release=$(echo $RELEASE)" >> $GITHUB_OUTPUT shell: bash diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 000000000..0e8a65477 --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,139 @@ +on: + workflow_call: + inputs: + module_directory: + type: string + description: The module directory + required: true + nfpm_file_pattern: + type: string + description: The pattern of the nfpm configuration file(s) + required: true + distrib: + type: string + description: The distrib + required: true + package_extension: + type: string + description: The package extension (deb or rpm) + required: true + image_name: + type: string + description: The image name + required: true + version: + type: string + description: The package version + required: true + release: + type: string + description: The release number + required: true + cache_key: + type: string + description: The package files cache key + required: true + +jobs: + package: + runs-on: ubuntu-22.04 + container: + image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ inputs.image_name }} + credentials: + username: ${{ secrets.DOCKER_REGISTRY_ID }} + password: ${{ secrets.DOCKER_REGISTRY_PASSWD }} + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Replace git sources by encoded files + if: "${{ inputs.encode_cache_key != '' }}" + run: | + rm -rf ${{ inputs.module_directory }} + tar zxf ${{ inputs.module_directory }}-${{ inputs.major_version }}.${{ inputs.minor_version }}.tar.gz + rm -f ${{ inputs.module_directory }}-${{ inputs.major_version }}.${{ inputs.minor_version }}.tar.gz + mv ${{ inputs.module_directory }}-${{ inputs.major_version }}.${{ inputs.minor_version }} ${{ inputs.module_directory }} + shell: bash + + - name: Restore static directory cache + if: "${{ inputs.frontend_static_directory != '' && inputs.frontend_static_cache_key != '' }}" + uses: actions/cache@v3 + with: + path: ${{ inputs.frontend_static_directory }} + key: ${{ inputs.frontend_static_cache_key }} + fail-on-cache-miss: true + + - name: Restore translation directory cache + if: "${{ inputs.translation_directory != '' && inputs.translation_cache_key != '' }}" + uses: actions/cache@v3 + with: + path: ${{ inputs.translation_directory }} + key: ${{ inputs.translation_cache_key }} + fail-on-cache-miss: true + + - name: Import gpg key + env: + RPM_GPG_SIGNING_KEY: ${{ secrets.RPM_GPG_SIGNING_KEY }} + run: echo -n "$RPM_GPG_SIGNING_KEY" > key.gpg + shell: bash + + - name: Build ${{ inputs.package_extension }} files + env: + RPM_GPG_SIGNING_KEY_ID: ${{ secrets.RPM_GPG_SIGNING_KEY_ID }} + RPM_GPG_SIGNING_PASSPHRASE: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }} + run: | + export MAJOR_VERSION="${{ inputs.major_version }}" + export VERSION="${{ inputs.major_version }}.${{ inputs.minor_version }}" + export RELEASE="${{ inputs.release }}" + + if [ "${{ inputs.package_extension }}" = "rpm" ]; then + export DIST=".${{ inputs.distrib }}" + export APACHE_USER="apache" + export APACHE_GROUP="apache" + else + export DIST="" + export APACHE_USER="www-data" + export APACHE_GROUP="www-data" + fi + + MAJOR_LEFT=$( echo $MAJOR_VERSION | cut -d "." -f1 ) + MAJOR_RIGHT=$( echo $MAJOR_VERSION | cut -d "-" -f1 | cut -d "." -f2 ) + BUMP_MAJOR_RIGHT=$(( MAJOR_RIGHT_PART + 1 )) + if [ "$MAJOR_RIGHT" = "04" ]; then + BUMP_MAJOR_LEFT="$MAJOR_LEFT" + BUMP_MAJOR_RIGHT="10" + else + BUMP_MAJOR_LEFT=$(( $MAJOR_LEFT + 1 )) + BUMP_MAJOR_RIGHT="04" + fi + + export NEXT_MAJOR_VERSION="$BUMP_MAJOR_LEFT.$BUMP_MAJOR_RIGHT" + + export RPM_SIGNING_KEY_FILE="$(pwd)/key.gpg" + export RPM_SIGNING_KEY_ID="$RPM_GPG_SIGNING_KEY_ID" + export NFPM_RPM_PASSPHRASE="$RPM_GPG_SIGNING_PASSPHRASE" + + for FILE in ${{ inputs.nfpm_file_pattern }}; do + DIRNAME=$(dirname $FILE) + BASENAME=$(basename $FILE) + cd $DIRNAME + sed -i "s/@COMMIT_HASH@/${{ github.sha }}/g" $BASENAME + nfpm package --config $BASENAME --packager ${{ inputs.package_extension }} + cd - + mv $DIRNAME/*.${{ inputs.package_extension }} ./ + done + shell: bash + + - name: Upload package artifacts + uses: actions/upload-artifact@v3 + with: + name: packages-${{ inputs.package_extension }} + path: ./*.${{ inputs.package_extension }} + retention-days: 1 + + - name: Cache packages + uses: actions/cache@v3 + with: + path: ./*.${{ inputs.package_extension }} + key: ${{ inputs.cache_key }} diff --git a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml new file mode 100644 index 000000000..21b027945 --- /dev/null +++ b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml @@ -0,0 +1,93 @@ +name: "centreon-plugin-Virtualization-VMWare-daemon" +arch: "all" +platform: "linux" +version_schema: "none" +version: "${VERSION}" +release: "${RELEASE}${DIST}" +section: "default" +priority: "optional" +maintainer: "Centreon " +description: | + Centreon VMWare connector to interact from centreon plugins to vmware sdk. + Commit: @COMMIT_HASH@ +vendor: "Centreon" +homepage: "https://centreon.com" +license: "Apache-2.0" + +replaces: + - ces-plugins-Virtualization-VMWare-daemon + - centreon-plugin-Virtualisation-VMWare-daemon +conflicts: + - ces-plugins-Virtualization-VMWare-daemon + - centreon-plugin-Virtualisation-VMWare-daemon +provides: + - ces-plugins-Virtualization-VMWare-daemon + - centreon-plugin-Virtualisation-VMWare-daemon + +contents: + - src: "../src/centreon/vmware" + dst: "/usr/share/perl5/vendor_perl/centreon/vmware" + packager: rpm + - src: "../src/centreon/vmware" + dst: "/usr/share/perl5/centreon/vmware" + packager: deb + + - src: "../src/centreon/script/centreon_vmware.pm" + dst: "/usr/share/perl5/vendor_perl/centreon/script/centreon_vmware.pm" + packager: rpm + - src: "../src/centreon/script/centreon_vmware.pm" + dst: "/usr/share/perl5/centreon/script/centreon_vmware.pm" + packager: deb + + - src: "../src/centreon_vmware.pl" + dst: "/usr/bin/centreon_vmware.pl" + file_info: + mode: 0755 + + - src: "../redhat/centreon_vmware-systemd" + dst: "/etc/systemd/system/centreon_vmware.service" + file_info: + mode: 0755 + packager: rpm + - src: "../debian/centreon_vmware-systemd" + dst: "/lib/systemd/system/centreon_vmware.service" + file_info: + mode: 0755 + packager: deb + + - src: "../redhat/centreon_vmware-sysconfig" + dst: "/etc/sysconfig/centreon_vmware" + packager: rpm + - src: "../debian/centreon_vmware-default" + dst: "/etc/default/centreon_vmware" + packager: deb + + - src: "../config/centreon_vmware-conf.pm" + dst: "/etc/centreon/centreon_vmware.pm" + type: config|noreplace + +overrides: + rpm: + depends: + - perl-VMware-vSphere >= 5.1 + - perl(ZMQ::LibZMQ4) + - perl(ZMQ::Constants) + - perl(LWP::Protocol::https) + - perl(IO::Socket::INET6) + - perl(JSON::XS) + - perl-Net-Curl + deb: + depends: + - perl-vmware-vsphere + - zmq-libzmq4-perl + - libzmq-constants-perl + - liblwp-protocol-https-perl + - libio-socket-inet6-perl + - libjson-xs-perl + - libnet-curl-perl + - libtext-template-perl + +rpm: + signature: + key_file: ${RPM_SIGNING_KEY_FILE} + key_id: ${RPM_SIGNING_KEY_ID} diff --git a/connectors/vmware/packaging/debian/centreon_vmware-default b/connectors/vmware/packaging/debian/centreon_vmware-default index a5aca771a..e67053299 100644 --- a/connectors/vmware/packaging/debian/centreon_vmware-default +++ b/connectors/vmware/packaging/debian/centreon_vmware-default @@ -1,9 +1,2 @@ -# Configuration for /etc/init.d/centreon_vmware - -# If run centcore at startup default: YES -RUN_AT_STARTUP="YES" - -# Centreon user default: root -CENTREON_USER="root" - +# centreon_vmware command line options OPTIONS="--logfile=/var/log/centreon_vmware.log --severity=error" \ No newline at end of file From adc0e3e991f16d7c907d8659e336e3a0e074d8ae Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 13:34:43 +0200 Subject: [PATCH 414/447] fix(ci): trigger properly vmware connector workflow --- .github/workflows/connector-vmware.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/connector-vmware.yml b/.github/workflows/connector-vmware.yml index 44f5c332e..a03b0dc66 100644 --- a/.github/workflows/connector-vmware.yml +++ b/.github/workflows/connector-vmware.yml @@ -8,15 +8,15 @@ on: workflow_dispatch: pull_request: paths: - - 'connectors/vmware/src' - - 'connectors/vmware/packaging' + - 'connectors/vmware/src/**' + - 'connectors/vmware/packaging/**' push: branches: - develop - master paths: - - 'connectors/vmware/src' - - 'connectors/vmware/packaging' + - 'connectors/vmware/src/**' + - 'connectors/vmware/packaging/**' tags: - centreon-connector-vmware-* From f04174cb34499cd06e0ee57e8e5ecf4ac53804ab Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 13:38:35 +0200 Subject: [PATCH 415/447] fix(ci): checkout sources to get version --- .github/workflows/get-environment.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/get-environment.yml b/.github/workflows/get-environment.yml index 7eb8785f9..fe41e6e73 100644 --- a/.github/workflows/get-environment.yml +++ b/.github/workflows/get-environment.yml @@ -24,6 +24,9 @@ jobs: release: ${{ steps.get_environment.outputs.release }} steps: + - name: Checkout sources + uses: actions/checkout@v3 + - id: get_environment run: | if [[ -z "$GITHUB_HEAD_REF" ]]; then From bcb34106508fec7fc806a6cd107d41ae2d8bd704 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 13:44:48 +0200 Subject: [PATCH 416/447] fix(ci): fix cmware connector workflow --- .github/workflows/connector-vmware.yml | 3 +- .github/workflows/package.yml | 45 +------------------------- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/.github/workflows/connector-vmware.yml b/.github/workflows/connector-vmware.yml index a03b0dc66..43cfd3f72 100644 --- a/.github/workflows/connector-vmware.yml +++ b/.github/workflows/connector-vmware.yml @@ -46,8 +46,7 @@ jobs: uses: ./.github/workflows/package.yml with: - module_directory: centreon-license-manager - nfpm_file_pattern: "centreon-license-manager/packaging/*.yaml" + nfpm_file_pattern: "connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml" distrib: ${{ matrix.distrib }} package_extension: ${{ matrix.package_extension }} image_name: ${{ matrix.image }} diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 0e8a65477..0ed4b35d9 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -1,10 +1,6 @@ on: workflow_call: inputs: - module_directory: - type: string - description: The module directory - required: true nfpm_file_pattern: type: string description: The pattern of the nfpm configuration file(s) @@ -47,31 +43,6 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 - - name: Replace git sources by encoded files - if: "${{ inputs.encode_cache_key != '' }}" - run: | - rm -rf ${{ inputs.module_directory }} - tar zxf ${{ inputs.module_directory }}-${{ inputs.major_version }}.${{ inputs.minor_version }}.tar.gz - rm -f ${{ inputs.module_directory }}-${{ inputs.major_version }}.${{ inputs.minor_version }}.tar.gz - mv ${{ inputs.module_directory }}-${{ inputs.major_version }}.${{ inputs.minor_version }} ${{ inputs.module_directory }} - shell: bash - - - name: Restore static directory cache - if: "${{ inputs.frontend_static_directory != '' && inputs.frontend_static_cache_key != '' }}" - uses: actions/cache@v3 - with: - path: ${{ inputs.frontend_static_directory }} - key: ${{ inputs.frontend_static_cache_key }} - fail-on-cache-miss: true - - - name: Restore translation directory cache - if: "${{ inputs.translation_directory != '' && inputs.translation_cache_key != '' }}" - uses: actions/cache@v3 - with: - path: ${{ inputs.translation_directory }} - key: ${{ inputs.translation_cache_key }} - fail-on-cache-miss: true - - name: Import gpg key env: RPM_GPG_SIGNING_KEY: ${{ secrets.RPM_GPG_SIGNING_KEY }} @@ -83,8 +54,7 @@ jobs: RPM_GPG_SIGNING_KEY_ID: ${{ secrets.RPM_GPG_SIGNING_KEY_ID }} RPM_GPG_SIGNING_PASSPHRASE: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }} run: | - export MAJOR_VERSION="${{ inputs.major_version }}" - export VERSION="${{ inputs.major_version }}.${{ inputs.minor_version }}" + export VERSION="${{ inputs.version }}" export RELEASE="${{ inputs.release }}" if [ "${{ inputs.package_extension }}" = "rpm" ]; then @@ -97,19 +67,6 @@ jobs: export APACHE_GROUP="www-data" fi - MAJOR_LEFT=$( echo $MAJOR_VERSION | cut -d "." -f1 ) - MAJOR_RIGHT=$( echo $MAJOR_VERSION | cut -d "-" -f1 | cut -d "." -f2 ) - BUMP_MAJOR_RIGHT=$(( MAJOR_RIGHT_PART + 1 )) - if [ "$MAJOR_RIGHT" = "04" ]; then - BUMP_MAJOR_LEFT="$MAJOR_LEFT" - BUMP_MAJOR_RIGHT="10" - else - BUMP_MAJOR_LEFT=$(( $MAJOR_LEFT + 1 )) - BUMP_MAJOR_RIGHT="04" - fi - - export NEXT_MAJOR_VERSION="$BUMP_MAJOR_LEFT.$BUMP_MAJOR_RIGHT" - export RPM_SIGNING_KEY_FILE="$(pwd)/key.gpg" export RPM_SIGNING_KEY_ID="$RPM_GPG_SIGNING_KEY_ID" export NFPM_RPM_PASSPHRASE="$RPM_GPG_SIGNING_PASSPHRASE" From 81c93ab234f5650c4b9a8cf5048d1695cbd7b5f3 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 13:49:20 +0200 Subject: [PATCH 417/447] fix(packaging): fix paths in vmware connector packaging file --- .../centreon-plugin-virtualization-vmware-daemon.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml index 21b027945..f0dc2b993 100644 --- a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml +++ b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml @@ -44,25 +44,25 @@ contents: file_info: mode: 0755 - - src: "../redhat/centreon_vmware-systemd" + - src: "redhat/centreon_vmware-systemd" dst: "/etc/systemd/system/centreon_vmware.service" file_info: mode: 0755 packager: rpm - - src: "../debian/centreon_vmware-systemd" + - src: "debian/centreon_vmware-systemd" dst: "/lib/systemd/system/centreon_vmware.service" file_info: mode: 0755 packager: deb - - src: "../redhat/centreon_vmware-sysconfig" + - src: "redhat/centreon_vmware-sysconfig" dst: "/etc/sysconfig/centreon_vmware" packager: rpm - - src: "../debian/centreon_vmware-default" + - src: "debian/centreon_vmware-default" dst: "/etc/default/centreon_vmware" packager: deb - - src: "../config/centreon_vmware-conf.pm" + - src: "config/centreon_vmware-conf.pm" dst: "/etc/centreon/centreon_vmware.pm" type: config|noreplace From 893fa0c9992ddace65183231eeec6aed6fe51026 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 13:56:50 +0200 Subject: [PATCH 418/447] fix(packaging): update description of vmware connector package --- .../packaging/centreon-plugin-virtualization-vmware-daemon.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml index f0dc2b993..ccf8a8874 100644 --- a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml +++ b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml @@ -8,7 +8,7 @@ section: "default" priority: "optional" maintainer: "Centreon " description: | - Centreon VMWare connector to interact from centreon plugins to vmware sdk. + Perl daemon to monitor VSphere Infrastructure Commit: @COMMIT_HASH@ vendor: "Centreon" homepage: "https://centreon.com" From 8de3c7838be006f7f9fba5af059d87363f2e016a Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 14:44:50 +0200 Subject: [PATCH 419/447] chore(ci): add deliver jobs to vmware connector workflow --- .github/workflows/connector-vmware.yml | 54 +++++++++++++++++++++++++- .github/workflows/package.yml | 2 +- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/.github/workflows/connector-vmware.yml b/.github/workflows/connector-vmware.yml index 43cfd3f72..03b21bae7 100644 --- a/.github/workflows/connector-vmware.yml +++ b/.github/workflows/connector-vmware.yml @@ -30,7 +30,6 @@ jobs: needs: - get-environment strategy: - fail-fast: false matrix: include: - package_extension: rpm @@ -54,3 +53,56 @@ jobs: release: ${{ needs.get-environment.outputs.release }} cache_key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-${{ matrix.distrib }} secrets: inherit + + deliver-rpm: + needs: + - get-environment + - package + if: ${{ contains(fromJson('["stable", "testing", "unstable"]'), needs.get-environment.outputs.stability) }} + runs-on: [self-hosted, common] + + strategy: + matrix: + distrib: [el8, el9] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Delivery + uses: ./.github/actions/rpm-delivery + with: + module_name: connector-vmware + distrib: ${{ matrix.distrib }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} + update_repo_path: ${{ secrets.UPDATE_REPO_PATH }} + cloudfront_id: ${{ secrets.CLOUDFRONT_ID }} + yum_repo_address: ${{ secrets.YUM_REPO_ADDRESS }} + yum_repo_key: ${{ secrets.YUM_REPO_KEY }} + stability: ${{ needs.get-environment.outputs.stability }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + + deliver-deb: + needs: + - get-environment + - package + if: ${{ contains(fromJson('["stable", "testing", "unstable"]'), needs.get-environment.outputs.stability) }} + runs-on: [self-hosted, common] + + strategy: + matrix: + distrib: [bullseye] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Delivery + uses: ./.github/actions/deb-delivery + with: + distrib: ${{ matrix.distrib }} + nexus_username: ${{ secrets.NEXUS_USERNAME }} + nexus_password: ${{ secrets.NEXUS_PASSWORD }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 0ed4b35d9..9c4b5d941 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -85,7 +85,7 @@ jobs: - name: Upload package artifacts uses: actions/upload-artifact@v3 with: - name: packages-${{ inputs.package_extension }} + name: packages-${{ inputs.distrib }} path: ./*.${{ inputs.package_extension }} retention-days: 1 From d8e2ec894ba700359c963e1dacfc009762d5f5ca Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 19 May 2023 15:17:04 +0200 Subject: [PATCH 420/447] fix(packaging): update zmq dependency --- .../packaging/centreon-plugin-virtualization-vmware-daemon.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml index ccf8a8874..5ad0112dd 100644 --- a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml +++ b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml @@ -79,7 +79,7 @@ overrides: deb: depends: - perl-vmware-vsphere - - zmq-libzmq4-perl + - libzmq-libzmq4-perl - libzmq-constants-perl - liblwp-protocol-https-perl - libio-socket-inet6-perl From f31d177eb1677a0b1fba030540f9135ed0e5ffe5 Mon Sep 17 00:00:00 2001 From: tcharles Date: Thu, 25 May 2023 10:19:25 +0200 Subject: [PATCH 421/447] apps::monitoring::splunk - improve splunk api handling (#4407) --- src/apps/monitoring/splunk/custom/api.pm | 60 +++++++++++++++++------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/src/apps/monitoring/splunk/custom/api.pm b/src/apps/monitoring/splunk/custom/api.pm index eee5369be..4badfc23a 100644 --- a/src/apps/monitoring/splunk/custom/api.pm +++ b/src/apps/monitoring/splunk/custom/api.pm @@ -54,7 +54,9 @@ sub new { 'timeout:s' => { name => 'timeout' }, 'unknown-http-status:s' => { name => 'unknown_http_status' }, 'warning-http-status:s' => { name => 'warning_http_status' }, - 'critical-http-status:s' => { name => 'critical_http_status' } + 'critical-http-status:s' => { name => 'critical_http_status' }, + 'splunk-retries:s' => { name => 'splunk_retries' }, + 'splunk-wait:s' => { name => 'splunk_wait' } }); } $options{options}->add_help(package => __PACKAGE__, sections => 'XMLAPI OPTIONS', once => 1); @@ -86,6 +88,8 @@ sub check_options { $self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300'; $self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : ''; $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : ''; + $self->{splunk_retries} = (defined($self->{option_results}->{splunk_retries})) ? $self->{option_results}->{splunk_retries} : 5; + $self->{splunk_wait} = (defined($self->{option_results}->{splunk_wait})) ? $self->{option_results}->{splunk_wait} : 2; if ($self->{hostname} eq '') { $self->{output}->add_option_msg(short_msg => 'Need to specify hostname option.'); @@ -200,7 +204,7 @@ sub get_access_token { $self->{output}->add_option_msg(short_msg => 'error retrieving session_token'); $self->{output}->option_exit(); } - + $session_token = $xml_result->{sessionKey}; my $datas = { session_token => $session_token }; @@ -251,7 +255,6 @@ sub get_splunkd_health { } return \@splunkd_features_health; - } sub query_count { @@ -270,27 +273,44 @@ sub query_count { $self->{output}->option_exit(); } - sleep(1.5); + my $retries = 0; + my $is_done = 0; - my $query_status = $self->request_api( - method => 'GET', - endpoint => '/services/search/jobs/' . $query_sid->{sid}, - ); + while ($retries < $self->{http}->{options}->{splunk_retries}) { + my $query_status = $self->request_api( + method => 'GET', + endpoint => '/services/search/jobs/' . $query_sid->{sid} + ); - foreach (@{$query_status->{content}->{'s:dict'}->{'s:key'}}) { - if ($_->{name} eq 'isDone' && $_->{content} == 0){ - $self->{output}->add_option_msg(short_msg => "Search command wasn't completed."); - $self->{output}->option_exit(); - } elsif ($_->{name} eq 'isFailed' && $_->{content} == 1) { - $self->{output}->add_option_msg(short_msg => "Search command failed."); - $self->{output}->option_exit(); + foreach (@{$query_status->{content}->{'s:dict'}->{'s:key'}}) { + if ($_->{name} eq 'isDone' && $_->{content} == 1){ + $is_done = 1; + last; + } elsif ($_->{name} eq 'isFailed' && $_->{content} == 1) { + $self->{output}->add_option_msg(short_msg => "Search command failed."); + $self->{output}->option_exit(); + } } + + if ($is_done) { + last; + } + + $retries++; + sleep($self->{http}->{options}->{splunk_wait}); + } + + # it took too long to run query + if (!$is_done) { + $self->{output}->add_option_msg(short_msg => "Search command didn't finish in time. Considere tweaking --splunk-wait and --splunk-retries if the search is just slow"); + $self->{output}->option_exit(); } my $query_res = $self->request_api( method => 'GET', - endpoint => '/services/search/jobs/' . $query_sid->{sid} . '/results', + endpoint => '/services/search/jobs/' . $query_sid->{sid} . '/results' ); + my $query_count = $query_res->{result}->{field}->{value}->{text}; return $query_count; @@ -387,6 +407,14 @@ Specify api password. Set HTTP timeout. +=item B<--splunk-retries> + +How many times we should retry queries to splunk. To use in par with the --splunk-wait paramater (Default: 5) + +=item B<--splunk-wait> + +How long (in seconds) should we wait between each retry. To use in par with the --splunk-retries paramater (Default: 2) + =back =head1 DESCRIPTION From b905c38edb9f1219e07d5112403db5863755eb4f Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 11:53:00 +0200 Subject: [PATCH 422/447] chore(packaging): package vmware-vsphere --- .github/workflows/package.yml | 29 +++- .github/workflows/perl-vmware-vsphere.yml | 128 ++++++++++++++++++ .../packaging/perl-vmware-vsphere.yaml | 69 ++++++++++ 3 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/perl-vmware-vsphere.yml create mode 100644 dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 9c4b5d941..23c6bd6e7 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -20,11 +20,19 @@ on: version: type: string description: The package version - required: true + required: false release: type: string description: The release number - required: true + required: false + source_cache_key: + type: string + description: The source files cache key + required: false + source_cache_path: + type: string + description: The source files path + required: false cache_key: type: string description: The package files cache key @@ -49,6 +57,14 @@ jobs: run: echo -n "$RPM_GPG_SIGNING_KEY" > key.gpg shell: bash + - if: ${{ inputs.source_cache_key != '' && inputs.source_cache_path != '' }} + name: Import source files + uses: actions/cache/restore@v3 + with: + path: ${{ inputs.source_cache_path }} + key: ${{ inputs.source_cache_key }} + fail-on-cache-miss: true + - name: Build ${{ inputs.package_extension }} files env: RPM_GPG_SIGNING_KEY_ID: ${{ secrets.RPM_GPG_SIGNING_KEY_ID }} @@ -67,6 +83,9 @@ jobs: export APACHE_GROUP="www-data" fi + export PERL_SITELIB="$(eval "$(perl -V:installsitelib)"; echo $installsitelib)" + export PERL_VENDORLIB="$(eval "$(perl -V:installvendorlib)"; echo $installvendorlib)" + export RPM_SIGNING_KEY_FILE="$(pwd)/key.gpg" export RPM_SIGNING_KEY_ID="$RPM_GPG_SIGNING_KEY_ID" export NFPM_RPM_PASSPHRASE="$RPM_GPG_SIGNING_PASSPHRASE" @@ -75,7 +94,11 @@ jobs: DIRNAME=$(dirname $FILE) BASENAME=$(basename $FILE) cd $DIRNAME - sed -i "s/@COMMIT_HASH@/${{ github.sha }}/g" $BASENAME + sed -i \ + "s/@COMMIT_HASH@/${{ github.sha }}/g" \ + "s#@PERL_SITELIB@#${PERL_SITELIB}#g" \ + "s#@PERL_VENDORLIB@#${PERL_VENDORLIB}#g" \ + $BASENAME nfpm package --config $BASENAME --packager ${{ inputs.package_extension }} cd - mv $DIRNAME/*.${{ inputs.package_extension }} ./ diff --git a/.github/workflows/perl-vmware-vsphere.yml b/.github/workflows/perl-vmware-vsphere.yml new file mode 100644 index 000000000..0008df581 --- /dev/null +++ b/.github/workflows/perl-vmware-vsphere.yml @@ -0,0 +1,128 @@ +name: perl-vmware-vsphere + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: + workflow_dispatch: + pull_request: + paths: + - 'dependencies/perl-vmware-vsphere/**' + push: + branches: + - develop + - master + paths: + - 'dependencies/perl-vmware-vsphere/**' + tags: + - perl-vmware-vsphere-* + +jobs: + get-environment: + uses: ./.github/workflows/get-environment.yml + with: + version_file: connectors/vmware/src/centreon/script/centreon_vmware.pm + + get-sources: + runs-on: ubuntu-22.04 + steps: + - name: Download vsphere cli sources + run: | + wget https://gitlab.labexposed.com/centreon-lab/perl-VMware-vSphere/-/raw/master/storage/VMware-vSphere-Perl-SDK-7.0.0-17698549.x86_64.tar.gz + tar zxf VMware-vSphere-Perl-SDK-7.0.0-17698549.x86_64.tar.gz + shell: bash + + - name: Build vsphere cli sources + run: | + cd vmware-vsphere-cli-distrib + perl Makefile.PL + make pure_install + shell: bash + + - name: Cache vsphere cli sources + uses: actions/cache/save@v3 + with: + path: vmware-vsphere-cli-distrib + key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere + + package: + needs: + - get-sources + strategy: + matrix: + include: + - package_extension: rpm + image: packaging-plugins-alma8 + distrib: el8 + - package_extension: rpm + image: packaging-plugins-alma9 + distrib: el9 + - package_extension: deb + image: packaging-plugins-bullseye + distrib: bullseye + name: package ${{ matrix.distrib }} + + uses: ./.github/workflows/package.yml + with: + nfpm_file_pattern: "dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml" + distrib: ${{ matrix.distrib }} + package_extension: ${{ matrix.package_extension }} + image_name: ${{ matrix.image }} + source_cache_key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere + source_cache_path: vmware-vsphere-cli-distrib + cache_key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-${{ matrix.distrib }} + secrets: inherit + + deliver-rpm: + needs: + - get-environment + - package + if: ${{ contains(fromJson('["stable", "testing", "unstable"]'), needs.get-environment.outputs.stability) }} + runs-on: [self-hosted, common] + + strategy: + matrix: + distrib: [el8, el9] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Delivery + uses: ./.github/actions/rpm-delivery + with: + module_name: connector-vmware + distrib: ${{ matrix.distrib }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} + update_repo_path: ${{ secrets.UPDATE_REPO_PATH }} + cloudfront_id: ${{ secrets.CLOUDFRONT_ID }} + yum_repo_address: ${{ secrets.YUM_REPO_ADDRESS }} + yum_repo_key: ${{ secrets.YUM_REPO_KEY }} + stability: ${{ needs.get-environment.outputs.stability }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + + deliver-deb: + needs: + - get-environment + - package + if: ${{ contains(fromJson('["stable", "testing", "unstable"]'), needs.get-environment.outputs.stability) }} + runs-on: [self-hosted, common] + + strategy: + matrix: + distrib: [bullseye] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Delivery + uses: ./.github/actions/deb-delivery + with: + distrib: ${{ matrix.distrib }} + nexus_username: ${{ secrets.NEXUS_USERNAME }} + nexus_password: ${{ secrets.NEXUS_PASSWORD }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} diff --git a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml new file mode 100644 index 000000000..0db1f001e --- /dev/null +++ b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml @@ -0,0 +1,69 @@ +name: "perl-VMware-vSphere" +arch: "amd64" +platform: "linux" +version_schema: "none" +version: "7.0.0" +release: "17698549${DIST}" +section: "default" +priority: "optional" +maintainer: "Centreon " +description: | + The vSphere SDK for Perl is a client-side Perl framework that provides an easy-to-use scripting interface to the vSphere API. + Administrators and developers who are familiar with Perl can use the vSphere SDK for Perl to automate a wide variety of administrative, provisioning, and monitoring tasks in the vSphere environment. + The vSphere SDK for Perl includes ready-to-use utility applications, which you can immediately put to use in your virtual datacenter. + + The vSphere SDK for Perl installation includes the WS-Management Perl Library, which allows you to write scripts that retrieve CIM data from the ESX host using CIMOM, a service that provides standard CIM management functions over a WBEM (Web-Based Enterprise Management). + + You can use the SDK to manage ESX 3.0.x, ESX/ESXi 3.5, ESX/ESXi 4.0, ESX/ESXi 4.1, ESXi 5.0, vCenter Server 2.5, vCenter Server 4.0, vCenter Server 4.1, and vCenter Server 5.0. + + Commit: @COMMIT_HASH@ +vendor: "vmware" +homepage: "https://vmware.com" +license: "GPLv2+" + +contents: + - src: "../../vmware-vsphere-cli-distrib/VMware" + dst: "@PERL_SITELIB@/VMware" + packager: rpm + - src: "../../vmware-vsphere-cli-distrib/VMware" + dst: "/usr/share/perl5/VMware" + packager: deb + + - src: "../../vmware-vsphere-cli-distrib/WSMan" + dst: "@PERL_SITELIB@/WSMan" + packager: rpm + - src: "../../vmware-vsphere-cli-distrib/WSMan" + dst: "/usr/share/perl5/WSMan" + packager: deb + +overrides: + rpm: + provides: + - perl(VMware::VIRuntime) + depends: + - perl-XML-LibXML >= 1.58 + - perl-libwww-perl >= 5.8.05 + - perl-SOAP-Lite >= 0.67 + - perl-UUID >= 0.03 + - perl-Class-MethodMaker >= 2.08 + deb: + depends: + - libstat-lsmode-perl + - libclass-methodmaker-perl + - libuuid-perl + - libconvert-binhex-perl + - libemail-date-format-perl + - libio-sessiondata-perl + - libmime-lite-perl + - libmime-types-perl + - libmime-tools-perl + - libmailtools-perl + - libnet-smtp-ssl-perl + - libsoap-lite-perl + - libtext-template-perl + +rpm: + compression: zstd + signature: + key_file: ${RPM_SIGNING_KEY_FILE} + key_id: ${RPM_SIGNING_KEY_ID} From 3fcf2ffeecaf4cb90a9342aa83be49dffe15332b Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 11:58:21 +0200 Subject: [PATCH 423/447] fix(packaging): add sudo to package vmware-vsphere --- .github/workflows/perl-vmware-vsphere.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/perl-vmware-vsphere.yml b/.github/workflows/perl-vmware-vsphere.yml index 0008df581..226a77ee0 100644 --- a/.github/workflows/perl-vmware-vsphere.yml +++ b/.github/workflows/perl-vmware-vsphere.yml @@ -37,7 +37,7 @@ jobs: run: | cd vmware-vsphere-cli-distrib perl Makefile.PL - make pure_install + sudo make pure_install shell: bash - name: Cache vsphere cli sources From f1f2345509b007fd08700e5f9c812279809e1321 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 12:04:16 +0200 Subject: [PATCH 424/447] fix(packaging): fix sed command in package workflow --- .github/workflows/package.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 23c6bd6e7..aef00f0ce 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -95,9 +95,7 @@ jobs: BASENAME=$(basename $FILE) cd $DIRNAME sed -i \ - "s/@COMMIT_HASH@/${{ github.sha }}/g" \ - "s#@PERL_SITELIB@#${PERL_SITELIB}#g" \ - "s#@PERL_VENDORLIB@#${PERL_VENDORLIB}#g" \ + "s/@COMMIT_HASH@/${{ github.sha }}/g; s#@PERL_SITELIB@#${PERL_SITELIB}#g; s#@PERL_VENDORLIB@#${PERL_VENDORLIB}#g" \ $BASENAME nfpm package --config $BASENAME --packager ${{ inputs.package_extension }} cd - From 3b0474f0deddecfcf5e13bce2620f495dde3ddc6 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 12:22:00 +0200 Subject: [PATCH 425/447] fix(packaging): fix paths to package vmware-vsphere --- .../packaging/perl-vmware-vsphere.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml index 0db1f001e..097314f1a 100644 --- a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml +++ b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml @@ -22,17 +22,17 @@ homepage: "https://vmware.com" license: "GPLv2+" contents: - - src: "../../vmware-vsphere-cli-distrib/VMware" + - src: "../../../vmware-vsphere-cli-distrib/VMware" dst: "@PERL_SITELIB@/VMware" packager: rpm - - src: "../../vmware-vsphere-cli-distrib/VMware" + - src: "../../../vmware-vsphere-cli-distrib/VMware" dst: "/usr/share/perl5/VMware" packager: deb - - src: "../../vmware-vsphere-cli-distrib/WSMan" + - src: "../../../vmware-vsphere-cli-distrib/WSMan" dst: "@PERL_SITELIB@/WSMan" packager: rpm - - src: "../../vmware-vsphere-cli-distrib/WSMan" + - src: "../../../vmware-vsphere-cli-distrib/WSMan" dst: "/usr/share/perl5/WSMan" packager: deb From af3e2c91188dfcd8552f5aad4d083080a584c2e1 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 12:54:14 +0200 Subject: [PATCH 426/447] chore(docker): install zstd --- .github/docker/Dockerfile.packaging-plugins-alma8 | 2 +- .github/docker/Dockerfile.packaging-plugins-alma9 | 2 +- .github/docker/Dockerfile.packaging-plugins-bullseye | 3 ++- .github/docker/Dockerfile.packaging-plugins-centos7 | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/docker/Dockerfile.packaging-plugins-alma8 b/.github/docker/Dockerfile.packaging-plugins-alma8 index 19fcc1b24..5337a9edb 100644 --- a/.github/docker/Dockerfile.packaging-plugins-alma8 +++ b/.github/docker/Dockerfile.packaging-plugins-alma8 @@ -10,7 +10,7 @@ baseurl=https://repo.goreleaser.com/yum/ enabled=1 gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo -dnf -y install git gettext rpm-build dos2unix python3 epel-release nfpm +dnf -y install git gettext rpm-build dos2unix python3 epel-release nfpm zstd dnf -y install perl-App-cpanminus perl-JSON cpanm App::FatPacker cpanm File::Copy::Recursive diff --git a/.github/docker/Dockerfile.packaging-plugins-alma9 b/.github/docker/Dockerfile.packaging-plugins-alma9 index d50e98351..458541df3 100644 --- a/.github/docker/Dockerfile.packaging-plugins-alma9 +++ b/.github/docker/Dockerfile.packaging-plugins-alma9 @@ -10,7 +10,7 @@ baseurl=https://repo.goreleaser.com/yum/ enabled=1 gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo -dnf -y install git gettext rpm-build dos2unix python3 epel-release nfpm +dnf -y install git gettext rpm-build dos2unix python3 epel-release nfpm zstd dnf -y install perl-App-cpanminus perl-JSON cpanm App::FatPacker cpanm File::Copy::Recursive diff --git a/.github/docker/Dockerfile.packaging-plugins-bullseye b/.github/docker/Dockerfile.packaging-plugins-bullseye index 88402f445..86136321a 100644 --- a/.github/docker/Dockerfile.packaging-plugins-bullseye +++ b/.github/docker/Dockerfile.packaging-plugins-bullseye @@ -38,7 +38,8 @@ apt-get install -y \ libjson-perl \ libapp-fatpacker-perl \ libfile-copy-recursive-perl \ - jq + jq \ + zstd echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list apt-get update diff --git a/.github/docker/Dockerfile.packaging-plugins-centos7 b/.github/docker/Dockerfile.packaging-plugins-centos7 index 99ae295fe..b43fc6571 100644 --- a/.github/docker/Dockerfile.packaging-plugins-centos7 +++ b/.github/docker/Dockerfile.packaging-plugins-centos7 @@ -10,7 +10,7 @@ baseurl=https://repo.goreleaser.com/yum/ enabled=1 gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo -yum -y install git gettext rpm-build dos2unix python3 epel-release nfpm +yum -y install git gettext rpm-build dos2unix python3 epel-release nfpm zstd yum -y install perl-App-FatPacker perl-File-Copy-Recursive perl-JSON yum clean all From 62a4ab9885453ff6572a555a9c69994de65046e3 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 13:52:09 +0200 Subject: [PATCH 427/447] fix(packaging): remove blank line in debian package description --- .../perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml index 097314f1a..2b3165ece 100644 --- a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml +++ b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml @@ -11,11 +11,8 @@ description: | The vSphere SDK for Perl is a client-side Perl framework that provides an easy-to-use scripting interface to the vSphere API. Administrators and developers who are familiar with Perl can use the vSphere SDK for Perl to automate a wide variety of administrative, provisioning, and monitoring tasks in the vSphere environment. The vSphere SDK for Perl includes ready-to-use utility applications, which you can immediately put to use in your virtual datacenter. - The vSphere SDK for Perl installation includes the WS-Management Perl Library, which allows you to write scripts that retrieve CIM data from the ESX host using CIMOM, a service that provides standard CIM management functions over a WBEM (Web-Based Enterprise Management). - You can use the SDK to manage ESX 3.0.x, ESX/ESXi 3.5, ESX/ESXi 4.0, ESX/ESXi 4.1, ESXi 5.0, vCenter Server 2.5, vCenter Server 4.0, vCenter Server 4.1, and vCenter Server 5.0. - Commit: @COMMIT_HASH@ vendor: "vmware" homepage: "https://vmware.com" From ac0823634df6dd440f0e36399f59629b0418abfb Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 15:08:38 +0200 Subject: [PATCH 428/447] fix(packaging): manage properle vmware config ile --- .../centreon-plugin-virtualization-vmware-daemon.yaml | 4 ++++ connectors/vmware/packaging/scripts/postinstall.sh | 7 +++++++ .../perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml | 1 + 3 files changed, 12 insertions(+) create mode 100644 connectors/vmware/packaging/scripts/postinstall.sh diff --git a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml index 5ad0112dd..165175b98 100644 --- a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml +++ b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml @@ -65,6 +65,10 @@ contents: - src: "config/centreon_vmware-conf.pm" dst: "/etc/centreon/centreon_vmware.pm" type: config|noreplace + packager: rpm + - src: "config/centreon_vmware-conf.pm" + dst: "/etc/centreon/centreon_vmware.pm.new" + packager: deb overrides: rpm: diff --git a/connectors/vmware/packaging/scripts/postinstall.sh b/connectors/vmware/packaging/scripts/postinstall.sh new file mode 100644 index 000000000..33b8a2557 --- /dev/null +++ b/connectors/vmware/packaging/scripts/postinstall.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ "$1" = "configure" ]; then # deb + if [ ! -f "/etc/centreon/centreon_vmware.pm" ]; then + mv /etc/centreon/centreon_vmware.pm.new /etc/centreon/centreon_vmware.pm + fi +fi diff --git a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml index 2b3165ece..ec0a6178a 100644 --- a/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml +++ b/dependencies/perl-vmware-vsphere/packaging/perl-vmware-vsphere.yaml @@ -58,6 +58,7 @@ overrides: - libnet-smtp-ssl-perl - libsoap-lite-perl - libtext-template-perl + - libxml-libxml-perl rpm: compression: zstd From d2368478124cba41c08a18506a20e5df817fb07e Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Mon, 29 May 2023 15:13:32 +0200 Subject: [PATCH 429/447] enh(packaging): add deb postinstall script --- .../centreon-plugin-virtualization-vmware-daemon.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml index 165175b98..8e54f62c1 100644 --- a/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml +++ b/connectors/vmware/packaging/centreon-plugin-virtualization-vmware-daemon.yaml @@ -70,6 +70,9 @@ contents: dst: "/etc/centreon/centreon_vmware.pm.new" packager: deb +scripts: + postinstall: ./scripts/postinstall.sh + overrides: rpm: depends: From c21e73006b61001aadbb685fa302c4ac098cb264 Mon Sep 17 00:00:00 2001 From: Jochen Platzgummer Date: Tue, 30 May 2023 09:22:04 +0200 Subject: [PATCH 430/447] wman dcdiag for italian language (#4432) --- src/apps/microsoft/activedirectory/wsman/mode/dcdiag.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/apps/microsoft/activedirectory/wsman/mode/dcdiag.pm b/src/apps/microsoft/activedirectory/wsman/mode/dcdiag.pm index 2beff1a9f..31fd956cb 100644 --- a/src/apps/microsoft/activedirectory/wsman/mode/dcdiag.pm +++ b/src/apps/microsoft/activedirectory/wsman/mode/dcdiag.pm @@ -129,6 +129,14 @@ sub read_config { a .*?chou. + + + Inizio test.*?:\s+(.*?)\n.*?(superato|warning|non ha superato) + superato + warning + non ha superato + + END_FILE From 97d7a8ba6d2fc466b10742cbf395d4da885766e6 Mon Sep 17 00:00:00 2001 From: Jochen Platzgummer Date: Tue, 30 May 2023 09:22:44 +0200 Subject: [PATCH 431/447] local dcdiag - add italian parsing (#4431) --- src/apps/microsoft/activedirectory/local/mode/dcdiag.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/apps/microsoft/activedirectory/local/mode/dcdiag.pm b/src/apps/microsoft/activedirectory/local/mode/dcdiag.pm index 098142e3f..a5bfd6598 100644 --- a/src/apps/microsoft/activedirectory/local/mode/dcdiag.pm +++ b/src/apps/microsoft/activedirectory/local/mode/dcdiag.pm @@ -107,6 +107,14 @@ sub read_config { a .*?chou. + + + Inizio test.*?:\s+(.*?)\n.*?(superato|warning|non ha superato) + superato + warning + non ha superato + + END_FILE From 8a4e3be5a7b9899422e4a1e55f43e3313bbabbf2 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 30 May 2023 09:23:04 +0200 Subject: [PATCH 432/447] (plugin) storage::emc::isilon::snmp - mode hardware fix power component filter (#4428) --- .../emc/isilon/snmp/mode/components/disk.pm | 23 +++++++++++-------- .../emc/isilon/snmp/mode/components/fan.pm | 23 ++++++++++++------- .../emc/isilon/snmp/mode/components/power.pm | 23 ++++++++++++------- .../snmp/mode/components/temperature.pm | 23 ++++++++++++------- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/src/storage/emc/isilon/snmp/mode/components/disk.pm b/src/storage/emc/isilon/snmp/mode/components/disk.pm index cbf6e8baf..3d1681427 100644 --- a/src/storage/emc/isilon/snmp/mode/components/disk.pm +++ b/src/storage/emc/isilon/snmp/mode/components/disk.pm @@ -27,7 +27,7 @@ my $mapping = { diskLogicalNumber => { oid => '.1.3.6.1.4.1.12124.2.52.1.2' }, diskChassisNumber => { oid => '.1.3.6.1.4.1.12124.2.52.1.3' }, diskDeviceName => { oid => '.1.3.6.1.4.1.12124.2.52.1.4' }, - diskStatus => { oid => '.1.3.6.1.4.1.12124.2.52.1.5' }, + diskStatus => { oid => '.1.3.6.1.4.1.12124.2.52.1.5' } }; my $oid_diskEntry = '.1.3.6.1.4.1.12124.2.52.1'; @@ -52,17 +52,22 @@ sub check { next if ($self->check_filter(section => 'disk', instance => $instance)); $self->{components}->{disk}->{total}++; - $self->{output}->output_add(long_msg => sprintf("disk '%s' status is '%s' [instance = %s] [logical = %s] [chassis = %s]", - $result->{diskDeviceName}, $result->{diskStatus}, $instance, - $result->{diskLogicalNumber}, $result->{diskChassisNumber} - )); - + $self->{output}->output_add( + long_msg => sprintf( + "disk '%s' status is '%s' [instance: %s] [logical: %s] [chassis: %s]", + $result->{diskDeviceName}, $result->{diskStatus}, $instance, + $result->{diskLogicalNumber}, $result->{diskChassisNumber} + ) + ); + my $exit = $self->get_severity(section => 'disk', value => $result->{diskStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Disk '%s' status is '%s'", $result->{diskDeviceName}, $result->{diskStatus})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Disk '%s' status is '%s'", $result->{diskDeviceName}, $result->{diskStatus}) + ); } } } -1; \ No newline at end of file +1; diff --git a/src/storage/emc/isilon/snmp/mode/components/fan.pm b/src/storage/emc/isilon/snmp/mode/components/fan.pm index e84843156..d72b3841f 100644 --- a/src/storage/emc/isilon/snmp/mode/components/fan.pm +++ b/src/storage/emc/isilon/snmp/mode/components/fan.pm @@ -52,23 +52,30 @@ sub check { next if ($self->check_filter(section => 'fan', instance => $instance)); $self->{components}->{fan}->{total}++; - $self->{output}->output_add(long_msg => sprintf("fan '%s' is %s rpm [instance = %s] [description = %s]", - $result->{fanName}, $result->{fanSpeed}, $instance, - $result->{fanDescription})); - + $self->{output}->output_add( + long_msg => sprintf( + "fan '%s' is %s rpm [instance = %s] [description = %s]", + $result->{fanName}, $result->{fanSpeed}, $instance, + $result->{fanDescription} + ) + ); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{fanSpeed}); - + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Fan '%s' is %s rpm", $result->{fanName}, $result->{fanSpeed})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Fan '%s' is %s rpm", $result->{fanName}, $result->{fanSpeed}) + ); } + $self->{output}->perfdata_add( label => 'speed', unit => 'rpm', nlabel => 'hardware.fan.speed.rpm', instances => $result->{fanName}, value => $result->{fanSpeed}, warning => $warn, - critical => $crit, + critical => $crit ); } } diff --git a/src/storage/emc/isilon/snmp/mode/components/power.pm b/src/storage/emc/isilon/snmp/mode/components/power.pm index 4161ebf29..e52d121c0 100644 --- a/src/storage/emc/isilon/snmp/mode/components/power.pm +++ b/src/storage/emc/isilon/snmp/mode/components/power.pm @@ -26,7 +26,7 @@ use warnings; my $mapping = { powerSensorName => { oid => '.1.3.6.1.4.1.12124.2.55.1.2' }, powerSensorDescription => { oid => '.1.3.6.1.4.1.12124.2.55.1.3' }, - powerSensorValue => { oid => '.1.3.6.1.4.1.12124.2.55.1.4' }, + powerSensorValue => { oid => '.1.3.6.1.4.1.12124.2.55.1.4' } }; my $oid_powerSensorEntry = '.1.3.6.1.4.1.12124.2.55.1'; @@ -52,16 +52,23 @@ sub check { next if ($self->check_filter(section => 'power', instance => $instance)); $self->{components}->{power}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Power '%s' sensor is %s [instance = %s] [description = %s]", - $result->{powerSensorName}, $result->{powerSensorValue}, $instance, - $result->{powerSensorDescription})); - - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{powerSensorValue}); + $self->{output}->output_add( + long_msg => sprintf( + "power '%s' sensor is %s [instance: %s] [description: %s]", + $result->{powerSensorName}, $result->{powerSensorValue}, $instance, + $result->{powerSensorDescription} + ) + ); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'power', instance => $instance, value => $result->{powerSensorValue}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Power '%s' sensor is %s (Volt or Amp)", $result->{powerSensorName}, $result->{powerSensorValue})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Power '%s' sensor is %s (Volt or Amp)", $result->{powerSensorName}, $result->{powerSensorValue}) + ); } + $self->{output}->perfdata_add( label => 'power', nlabel => 'hardware.power.sensor.count', diff --git a/src/storage/emc/isilon/snmp/mode/components/temperature.pm b/src/storage/emc/isilon/snmp/mode/components/temperature.pm index 29a7715f2..4e089cfb7 100644 --- a/src/storage/emc/isilon/snmp/mode/components/temperature.pm +++ b/src/storage/emc/isilon/snmp/mode/components/temperature.pm @@ -26,7 +26,7 @@ use warnings; my $mapping = { tempSensorName => { oid => '.1.3.6.1.4.1.12124.2.54.1.2' }, tempSensorDescription => { oid => '.1.3.6.1.4.1.12124.2.54.1.3' }, - tempSensorValue => { oid => '.1.3.6.1.4.1.12124.2.54.1.4' }, + tempSensorValue => { oid => '.1.3.6.1.4.1.12124.2.54.1.4' } }; my $oid_tempSensorEntry = '.1.3.6.1.4.1.12124.2.54.1'; @@ -52,23 +52,30 @@ sub check { next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; - $self->{output}->output_add(long_msg => sprintf("temperature '%s' is %s C [instance = %s] [description = %s]", - $result->{tempSensorName}, $result->{tempSensorValue}, $instance, - $result->{tempSensorDescription})); - + $self->{output}->output_add( + long_msg => sprintf( + "temperature '%s' is %s C [instance: %s] [description: %s]", + $result->{tempSensorName}, $result->{tempSensorValue}, $instance, + $result->{tempSensorDescription} + ) + ); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{tempSensorValue}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Temperature '%s' is %s C", $result->{tempSensorName}, $result->{tempSensorValue})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Temperature '%s' is %s C", $result->{tempSensorName}, $result->{tempSensorValue}) + ); } + $self->{output}->perfdata_add( label => 'temperature', unit => 'C', nlabel => 'hardware.temperature.celsius', instances => $result->{tempSensorName}, value => $result->{tempSensorValue}, warning => $warn, - critical => $crit, + critical => $crit ); } } From 053854e1c13429aea705398006f7cce1557b4b57 Mon Sep 17 00:00:00 2001 From: Lucie Dubrunfaut <123162035+lucie-dubrunfaut@users.noreply.github.com> Date: Tue, 30 May 2023 09:23:41 +0200 Subject: [PATCH 433/447] add cambium cnpilot series plugin (#4418) --- .../cnpilot/snmp/mode/connectionstatus.pm | 142 +++++++++++++ src/network/cambium/cnpilot/snmp/mode/cpu.pm | 129 ++++++++++++ .../cambium/cnpilot/snmp/mode/interfaces.pm | 182 ++++++++++++++++ .../cambium/cnpilot/snmp/mode/listradios.pm | 140 +++++++++++++ .../cambium/cnpilot/snmp/mode/memory.pm | 139 ++++++++++++ .../cambium/cnpilot/snmp/mode/radios.pm | 198 ++++++++++++++++++ src/network/cambium/cnpilot/snmp/plugin.pm | 52 +++++ 7 files changed, 982 insertions(+) create mode 100644 src/network/cambium/cnpilot/snmp/mode/connectionstatus.pm create mode 100644 src/network/cambium/cnpilot/snmp/mode/cpu.pm create mode 100644 src/network/cambium/cnpilot/snmp/mode/interfaces.pm create mode 100644 src/network/cambium/cnpilot/snmp/mode/listradios.pm create mode 100644 src/network/cambium/cnpilot/snmp/mode/memory.pm create mode 100644 src/network/cambium/cnpilot/snmp/mode/radios.pm create mode 100644 src/network/cambium/cnpilot/snmp/plugin.pm diff --git a/src/network/cambium/cnpilot/snmp/mode/connectionstatus.pm b/src/network/cambium/cnpilot/snmp/mode/connectionstatus.pm new file mode 100644 index 000000000..4bc496c3f --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/mode/connectionstatus.pm @@ -0,0 +1,142 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package network::cambium::cnpilot::snmp::mode::connectionstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_connection_output { + my ($self, %options) = @_; + + return "Access point '" . $options{instance_value}->{name} . "' "; +} + +sub custom_connection_output { + my ($self, %options) = @_; + + return sprintf( + 'connection status: %s', + $self->{result_values}->{connection_status} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'connection', type => 1, cb_prefix_output => 'prefix_connection_output', message_multiple => 'All connection status are ok' } + ]; + + $self->{maps_counters}->{connection} = [ + { label => 'connection-status', type => 2, + set => { + key_values => [ { name => 'connection_status' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_connection_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-ap:s' => { name => 'filter_ap' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + cambiumAPName => { oid => '.1.3.6.1.4.1.17713.22.1.1.1.2' }, + cambiumAPCnmConstaus => { oid => '.1.3.6.1.4.1.17713.22.1.1.1.12' } + }; + + # Point at the begining of the table + my $oid_cambiumAccessPointEntry = '.1.3.6.1.4.1.17713.22.1.1.1'; + + my $connectionstatus_result = $options{snmp}->get_table( + oid => $oid_cambiumAccessPointEntry, + nothing_quit => 1 + ); + + $self->{connection} = {}; + foreach my $oid (keys %{$connectionstatus_result}) { + next if ($oid !~ /^$mapping->{cambiumAPName}->{oid}\.(.*)$/); + # Catch instance in table + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $connectionstatus_result, instance => $instance); + + if (defined($self->{option_results}->{filter_ap}) && $self->{option_results}->{filter_ap} ne '' && + $result->{cambiumAPName} !~ /$self->{option_results}->{filter_ap}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{cambiumAPName} . "': no matching filter.", debug => 1); + next; + } + + $self->{connection}->{$instance} = { + name => $result->{cambiumAPName}, + connection_status => $result->{cambiumAPCnmConstaus} + }; + + } + + if (scalar(keys %{$self->{connection}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No AP matching with filter found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Connection status. + +=over 8 + +=item B<--filter-ap> + +Filter on one or several AP. + +=item B<--warning-connection-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--critical-connection-status> + +Set critical threshold for status. +Can used special variables like: %{status}, %{name} + +=back + +=cut diff --git a/src/network/cambium/cnpilot/snmp/mode/cpu.pm b/src/network/cambium/cnpilot/snmp/mode/cpu.pm new file mode 100644 index 000000000..d9b01f2ba --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/mode/cpu.pm @@ -0,0 +1,129 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package network::cambium::cnpilot::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{name} . "' usage: "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPUs are ok' } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'cpu-usage-prct', nlabel => 'cpu.usage.percentage', set => { + key_values => [ { name => 'cpu_usage' }, { name => 'name' } ], + output_template => '%.2f %%', + perfdatas => [ + { label => 'cpu', template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'name' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-ap:s' => { name => 'filter_ap' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # Select relevant oids for CPU monitoring + my $mapping = { + cambiumAPName => { oid => '.1.3.6.1.4.1.17713.22.1.1.1.2' }, + cambiumAPCPUUtilization => { oid => '.1.3.6.1.4.1.17713.22.1.1.1.6' } + }; + + # Point at the begining of the table + my $oid_cambiumAccessPointEntry = '.1.3.6.1.4.1.17713.22.1.1.1'; + + my $cpu_result = $options{snmp}->get_table( + oid => $oid_cambiumAccessPointEntry, + nothing_quit => 1 + ); + + foreach my $oid (keys %{$cpu_result}) { + next if ($oid !~ /^$mapping->{cambiumAPName}->{oid}\.(.*)$/); + # Catch instance in table + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $cpu_result, instance => $instance); + + if (defined($self->{option_results}->{filter_ap}) && $self->{option_results}->{filter_ap} ne '' && + $result->{cambiumAPName} !~ /$self->{option_results}->{filter_ap}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{cambiumAPName} . "': no matching filter.", debug => 1); + next; + } + + $self->{cpu}->{$instance} = { + name => $result->{cambiumAPName}, + cpu_usage => $result->{cambiumAPCPUUtilization} + }; + } + + if (scalar(keys %{$self->{cpu}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No AP matching with filter found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-ap> + +Filter on one AP name. + +=item B<--warning> + +Warning threshold for CPU. + +=item B<--critical> + +Critical threshold for CPU. + +=back + +=cut diff --git a/src/network/cambium/cnpilot/snmp/mode/interfaces.pm b/src/network/cambium/cnpilot/snmp/mode/interfaces.pm new file mode 100644 index 000000000..377c78007 --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/mode/interfaces.pm @@ -0,0 +1,182 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::cambium::cnpilot::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--check-metrics> + +If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast', +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', 'bps', 'counter'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--units-cast> + +Units of thresholds for communication types (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'counter'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--map-speed-dsl> + +Get interface speed configuration for interface type 'adsl' and 'vdsl2'. + +Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name + +E.g: --map-speed-dsl=Et0.835,Et0-vdsl2 + +=item B<--force-counters64> + +Force to use 64 bits counters only. Can be used to improve performance. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/src/network/cambium/cnpilot/snmp/mode/listradios.pm b/src/network/cambium/cnpilot/snmp/mode/listradios.pm new file mode 100644 index 000000000..23042cf7d --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/mode/listradios.pm @@ -0,0 +1,140 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package network::cambium::cnpilot::snmp::mode::listradios; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + # Select relevant oids for discovery function for Radio CnPilot + my $mapping = { + cambiumRadioIndex => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.1' }, + cambiumRadioMACAddress => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.2' }, + cambiumBandType => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.3' }, + cambiumRadioState => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.13' }, + cambiumRadioChannel => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.6' } + }; + + # Point at the begining of the table + my $oid_cambiumRadioEntry = '.1.3.6.1.4.1.17713.22.1.2.1'; + + my $snmp_result = $options{snmp}->get_table( + oid => $oid_cambiumRadioEntry, + nothing_quit => 1 + ); + + my $results = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{cambiumRadioMACAddress}->{oid}\.(.*)$/); + # Catch instance in table + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $results->{$result->{cambiumRadioMACAddress}} = { + id => $result->{cambiumRadioIndex}, + name => $result->{cambiumRadioMACAddress}, + band_type => $result->{cambiumBandType}, + transmit_power => $result->{cambiumRadioState}, + radio_channel => $result->{cambiumRadioChannel} + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(snmp => $options{snmp}); + foreach my $oid_path (sort keys %$results) { + $self->{output}->output_add( + long_msg => sprintf( + '[id: %s][name: %s][radio channel: %s][transmit power: %s][band type: %s]', + $results->{$oid_path}->{id}, + $results->{$oid_path}->{name}, + $results->{$oid_path}->{radio_channel}, + $results->{$oid_path}->{transmit_power}, + $results->{$oid_path}->{band_type} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List Radio' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['id', 'name', 'radio_channel', 'transmit_power', 'band_type']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(snmp => $options{snmp}); + foreach my $oid_path (sort keys %$results) { + $self->{output}->add_disco_entry( + id => $results->{$oid_path}->{id}, + name => $results->{$oid_path}->{name}, + radio_channel => $results->{$oid_path}->{radio_channel}, + transmit_power => $results->{$oid_path}->{transmit_power}, + band_type => $results->{$oid_path}->{band_type} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List radio interfaces. + +=over 8 + +=back + +=cut diff --git a/src/network/cambium/cnpilot/snmp/mode/memory.pm b/src/network/cambium/cnpilot/snmp/mode/memory.pm new file mode 100644 index 000000000..9bcb7bd4e --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/mode/memory.pm @@ -0,0 +1,139 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package network::cambium::cnpilot::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{name} . "' "; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + return sprintf( + 'used: %.2f %%', + $self->{result_values}->{used} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memories are ok' } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'memory-usage-prct', nlabel => 'memory.usage.percentage', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { template => '%s', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'name'} + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-ap:s' => { name => 'filter_ap' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # Select relevant oids for Memory monitoring + my $mapping = { + cambiumAPName => { oid => '.1.3.6.1.4.1.17713.22.1.1.1.2' }, + cambiumAPMemoryFree => { oid => '.1.3.6.1.4.1.17713.22.1.1.1.7' } + }; + + # Point at the begining of the table + my $oid_cambiumAccessPointEntry = '.1.3.6.1.4.1.17713.22.1.1.1'; + + my $memory_result = $options{snmp}->get_table( + oid => $oid_cambiumAccessPointEntry, + nothing_quit => 1 + ); + + foreach my $oid (keys %{$memory_result}) { + next if ($oid !~ /^$mapping->{cambiumAPName}->{oid}\.(.*)$/); + # Catch instance in table + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $memory_result, instance => $instance); + + if (defined($self->{option_results}->{filter_ap}) && $self->{option_results}->{filter_ap} ne '' && + $result->{cambiumAPName} !~ /$self->{option_results}->{filter_ap}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{cambiumAPName} . "': no matching filter.", debug => 1); + next; + } + + $self->{memory}->{$instance} = { + name => $result->{cambiumAPName}, + free => $result->{cambiumAPMemoryFree}, + used => 100 - $result->{cambiumAPMemoryFree} + }; + } + + if (scalar(keys %{$self->{memory}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No AP matching with filter found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--filter-ap> + +Filter on one or several AP. + +=item B<--warning> + +Warning threshold for Memory. + +=item B<--critical> + +Critical threshold for Memory. + +=back + +=cut diff --git a/src/network/cambium/cnpilot/snmp/mode/radios.pm b/src/network/cambium/cnpilot/snmp/mode/radios.pm new file mode 100644 index 000000000..ffea2e933 --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/mode/radios.pm @@ -0,0 +1,198 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package network::cambium::cnpilot::snmp::mode::radios; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use Digest::MD5 qw(md5_hex); + +sub prefix_radio_output { + my ($self, %options) = @_; + + return "radio interface '" . $options{instance_value}->{name} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'radios', type => 1, cb_prefix_output => 'prefix_radio_output', message_multiple => 'All raadio interfaces are ok' } + ]; + + $self->{maps_counters}->{radios} = [ + { label => 'clients-connected', nlabel => 'radio.clients.connected.count', set => { + key_values => [ { name => 'num_clients' }, { name => 'name' } ], + output_template => 'clients connected: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'name' } + ] + } + }, + { label => 'status', type => 2, critical_default => '%{state} eq "off"', + set => { + key_values => [ { name => 'state' }, { name => 'name' } ], + output_template => 'state: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'noise-floor', nlabel => 'radio.interface.noise.floor.dbm', set => { + key_values => [ { name => 'noise_floor' } ], + output_template => 'noise floor: %s dBm', + perfdatas => [ + { template => '%s', min => 0, unit => 'dBm', label_extra_instance => 1, instance_use => 'name' } + ] + } + }, + { label => 'interference', nlabel => 'radio.interface.interference.dbm', set => { + key_values => [ { name => 'interference' } ], + output_template => 'interference: %s dBm', + perfdatas => [ + { template => '%s', min => 0, unit => 'dBm', label_extra_instance => 1, instance_use => 'name' } + ] + } + }, + { label => 'traffic-in', nlabel => 'radio.interface.traffic.in.bitspersecond', set => { + key_values => [ { name => 'traffic_in', per_second => 1 } ], + output_template => 'in: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { template => '%s', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'name' } + ] + } + }, + { label => 'traffic-out', nlabel => 'radio.interface.traffic.out.bitspersecond', set => { + key_values => [ { name => 'traffic_out', per_second => 1 } ], + output_template => 'out: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { template => '%s', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'name' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # Select relevant oids for radio monitoring + my $mapping = { + cambiumRadioMACAddress => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.2' }, + cambiumRadioNumClients => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.5' }, + cambiumRadioTxDataBytes => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.9' }, + cambiumRadioRxDataBytes => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.10' }, + cambiumRadioState => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.13' }, + cambiumRadioNoiseFloor => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.16' }, + cambiumRadioInterference => { oid => '.1.3.6.1.4.1.17713.22.1.2.1.17' } + }; + + # Point at the begining of the table + my $oid_cambiumRadioPointEntry = '.1.3.6.1.4.1.17713.22.1.2.1'; + + my $radio_result = $options{snmp}->get_table( + oid => $oid_cambiumRadioPointEntry, + nothing_quit => 1 + ); + + foreach my $oid (keys %{$radio_result}) { + next if ($oid !~ /^$mapping->{cambiumRadioMACAddress}->{oid}\.(.*)$/); + # Catch instance in table + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $radio_result, instance => $instance); + + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{cambiumRadioMACAddress} !~ /$self->{option_results}->{filter_name}/); + + $self->{radios}->{$instance} = { + name => $result->{cambiumRadioMACAddress}, + num_clients => $result->{cambiumRadioNumClients}, + state => lc($result->{cambiumRadioState}), + traffic_out => $result->{cambiumRadioTxDataBytes} * 8, + traffic_in => $result->{cambiumRadioRxDataBytes} * 8, + noise_floor => $result->{cambiumRadioNoiseFloor}, + interference => $result->{cambiumRadioInterference} + }; + } + + if (scalar(keys %{$self->{radios}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No MACAddress matching with filter found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = 'cambium_cnpilot_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + md5_hex( + (defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : '') . '_' . + (defined($self->{option_results}->{filter_name}) ? $self->{option_results}->{filter_name} : '') + ); +} + +1; + +__END__ + +=head1 MODE + +Check radio interfaces. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--filter-name> + +Filter interface by MACAdress + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} eq "expired"'). +Can used special variables like: %{status}, %{name} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'clients-connected', 'noise-floor', 'interference', 'traffic-in', 'traffic-out'. + +=back + +=cut diff --git a/src/network/cambium/cnpilot/snmp/plugin.pm b/src/network/cambium/cnpilot/snmp/plugin.pm new file mode 100644 index 000000000..326b2f56f --- /dev/null +++ b/src/network/cambium/cnpilot/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::cambium::cnpilot::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'connection-status' => 'network::cambium::cnpilot::snmp::mode::connectionstatus', + 'cpu' => 'network::cambium::cnpilot::snmp::mode::cpu', + 'interfaces' => 'network::cambium::cnpilot::snmp::mode::interfaces', + 'list-radios' => 'network::cambium::cnpilot::snmp::mode::listradios', + 'memory' => 'network::cambium::cnpilot::snmp::mode::memory', + 'radios' => 'network::cambium::cnpilot::snmp::mode::radios' + }; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cambium cnPilot equipments through SNMP. + +=cut From 6d7d9a809c46f84044ff0afdfc9e04208adf323f Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Thu, 1 Jun 2023 09:36:46 +0200 Subject: [PATCH 434/447] fix(ci): fix directory name for unstable delivery (#4439) Refs: MON-19158 --- .github/workflows/perl-vmware-vsphere.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/perl-vmware-vsphere.yml b/.github/workflows/perl-vmware-vsphere.yml index 226a77ee0..c4bc51aae 100644 --- a/.github/workflows/perl-vmware-vsphere.yml +++ b/.github/workflows/perl-vmware-vsphere.yml @@ -92,7 +92,7 @@ jobs: - name: Delivery uses: ./.github/actions/rpm-delivery with: - module_name: connector-vmware + module_name: perl-vmware-vsphere distrib: ${{ matrix.distrib }} cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} update_repo_path: ${{ secrets.UPDATE_REPO_PATH }} From e4a71322a8852f0ee60df3661f7ce5421837e6e9 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Thu, 1 Jun 2023 09:45:34 +0200 Subject: [PATCH 435/447] enh(ci): deliver separately to legacy repositories (#4436) Refs: MON-19115 --- .../actions/deb-delivery-legacy/action.yml | 46 +++++++++ .github/actions/deb-delivery/action.yml | 18 +--- .../actions/rpm-delivery-legacy/action.yml | 96 +++++++++++++++++++ .github/actions/rpm-delivery/action.yml | 72 -------------- .github/workflows/connector-vmware.yml | 6 -- .github/workflows/perl-vmware-vsphere.yml | 6 -- .github/workflows/plugin-delivery.yml | 43 ++++++++- .github/workflows/plugin-package.yml | 14 +-- .github/workflows/plugins.yml | 14 ++- 9 files changed, 196 insertions(+), 119 deletions(-) create mode 100644 .github/actions/deb-delivery-legacy/action.yml create mode 100644 .github/actions/rpm-delivery-legacy/action.yml diff --git a/.github/actions/deb-delivery-legacy/action.yml b/.github/actions/deb-delivery-legacy/action.yml new file mode 100644 index 000000000..00cba4df8 --- /dev/null +++ b/.github/actions/deb-delivery-legacy/action.yml @@ -0,0 +1,46 @@ +name: "deb-delivery-legacy" +description: "Deliver legacy DEB packages" +inputs: + distrib: + description: "The distribution used for packaging" + required: true + major_version: + description: "The major version" + required: true + nexus_username: + description: The nexus username + required: true + nexus_password: + description: The nexus password + required: true + cache_key: + description: "The cached package key" + required: true + stability: + description: "The package stability (stable, testing, unstable)" + required: true + +runs: + using: "composite" + steps: + - name: Use cache DEB files + uses: actions/cache@v3 + with: + path: ./*.deb + key: ${{ inputs.cache_key }} + + - name: Publish DEBs to Nexus + run: | + echo "Delivering to ${{ inputs.major_version }} ${{ inputs.stability }}" + + FOLDER_SUFFIX="-${{ inputs.stability }}" + if [[ "${{ inputs.stability }}" == "stable" ]]; then + FOLDER_SUFFIX="" + fi + + for FILE in *.deb; do + sleep 2 + echo "Delivering $FILE" + curl --connect-timeout 10 --retry 2 --retry-max-time 30 --fail --silent --show-error -u '${{ inputs.nexus_username }}':'${{ inputs.nexus_password }}' -H 'Content-Type: multipart/form-data' --data-binary "@./$FILE" https://apt.centreon.com/repository/${{ inputs.major_version }}$FOLDER_SUFFIX/ || echo "::error::Fail to deliver $FILE ${{ inputs.major_version }}" + done + shell: bash diff --git a/.github/actions/deb-delivery/action.yml b/.github/actions/deb-delivery/action.yml index 892338fe7..6d57f6f98 100644 --- a/.github/actions/deb-delivery/action.yml +++ b/.github/actions/deb-delivery/action.yml @@ -1,5 +1,5 @@ -name: "deb-package" -description: "Package DEB Centreon" +name: "deb-delivery" +description: "Deliver DEB packages" inputs: distrib: description: "The distribution used for packaging" @@ -38,17 +38,3 @@ runs: run: | jf rt upload "*.deb" "apt-plugins-${{ inputs.stability }}/pool/" --deb "${{ inputs.distrib }}/main/all" shell: bash - - - name: Publish DEBs to Nexus - run: | - for MAJOR in "22.04" "22.10"; do - echo "Delivering to $MAJOR ${{ inputs.stability }}" - - FOLDER_SUFFIX="-${{ inputs.stability }}" - if [[ "${{ inputs.stability }}" == "stable" ]]; then - FOLDER_SUFFIX="" - fi - - find -name "*.deb" -print0 | xargs -0 -t -I % -P 2 sh -c "curl --connect-timeout 10 --retry 2 --retry-max-time 30 --fail --silent --show-error -u '${{ inputs.nexus_username }}':'${{ inputs.nexus_password }}' -H 'Content-Type: multipart/form-data' --data-binary '@%' https://apt.centreon.com/repository/$MAJOR$FOLDER_SUFFIX/ >/dev/null || exit 255" || break - done - shell: bash diff --git a/.github/actions/rpm-delivery-legacy/action.yml b/.github/actions/rpm-delivery-legacy/action.yml new file mode 100644 index 000000000..dba196186 --- /dev/null +++ b/.github/actions/rpm-delivery-legacy/action.yml @@ -0,0 +1,96 @@ +name: "rpm-delivery-legacy" +description: "rpm delivery in legacy repositories" +inputs: + module_name: + description: "The package module name" + required: true + major_version: + description: "The major version" + required: true + distrib: + description: "The distribution used for packaging" + required: true + cache_key: + description: "The cached package key" + required: true + yum_repo_url: + description: "The legacy yum repo url" + required: true + update_repo_path: + description: "The update repo script path" + required: true + cloudfront_id: + description: "The cloudfront ID for repo url" + required: true + yum_repo_address: + description: "The legacy yum repo address" + required: true + yum_repo_key: + description: "The repo key" + required: true + stability: + description: "The package stability (stable, testing, unstable)" + required: true + +runs: + using: "composite" + steps: + - name: Use cache RPM files + uses: actions/cache@v3 + with: + path: ./*.rpm + key: ${{ inputs.cache_key }} + + - name: Setup awscli + run: | + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + sudo unzip -q awscliv2.zip + sudo ./aws/install + shell: bash + + - name: Publish RPMs to standard repositories + run: | + FILES="*.rpm" + + REPOTYPE="${{ inputs.stability }}" + PROJECT_PATH="standard" + DISTRIB="${{ inputs.distrib }}" + ARCH="noarch" + + eval `ssh-agent` + ssh-add - <<< "${{ inputs.yum_repo_key }}" + + echo "Delivering to ${{ inputs.major_version }} $REPOTYPE" + + if [ "$REPOTYPE" == "stable" ]; then + TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/${{ inputs.major_version }}/$DISTRIB/$REPOTYPE/$ARCH/RPMS" + else + TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/${{ inputs.major_version }}/$DISTRIB/$REPOTYPE/$ARCH/${{ inputs.module_name }}" + PROJECT_LOCATION="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/${{ inputs.major_version }}/$DISTRIB/$REPOTYPE/$ARCH/${{ inputs.module_name }}" + fi + + echo "[DEBUG] - Target : $TARGET" + echo "[DEBUG] - PROJECT_LOCATION : $PROJECT_LOCATION" + + ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" mkdir -p "$TARGET" + scp -o StrictHostKeyChecking=no ./*.rpm "${{ inputs.yum_repo_address }}:$TARGET" + + # Update repository metadata + METADATAS="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/${{ inputs.major_version }}/$DISTRIB/$REPOTYPE/$ARCH" + sleep $((RANDOM % 120)) # wait random time to avoid simultaneous createrepo + ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" "sh "${{ inputs.update_repo_path }}" $METADATAS" 2>&- + + # Invalidate cloudfront cache + ID="${{ inputs.cloudfront_id }}" + PATHS="/$PROJECT_PATH/${{ inputs.major_version }}/$DISTRIB/$REPOTYPE/$ARCH/*" + ITERATIONS=1 + + until aws cloudfront create-invalidation --distribution-id "$ID" --paths "$PATHS"; do + if [ ${ITERATIONS} -eq 10 ]; then + return 0 + fi + echo "couldn't invalidate cache, AWS quota might have been reached, retrying in 30 seconds..." + sleep 30s + ITERATIONS=$((ITERATIONS+1)) + done + shell: bash diff --git a/.github/actions/rpm-delivery/action.yml b/.github/actions/rpm-delivery/action.yml index fcddf4e84..99b16e438 100644 --- a/.github/actions/rpm-delivery/action.yml +++ b/.github/actions/rpm-delivery/action.yml @@ -10,21 +10,6 @@ inputs: cache_key: description: "The cached package key" required: true - yum_repo_url: - description: "The legacy yum repo url" - required: true - update_repo_path: - description: "The update repo script path" - required: true - cloudfront_id: - description: "The cloudfront ID for repo url" - required: true - yum_repo_address: - description: "The legacy yum repo address" - required: true - yum_repo_key: - description: "The repo key" - required: true stability: description: "The package stability (stable, testing, unstable)" required: true @@ -84,60 +69,3 @@ runs: fi done shell: bash - - - name: Setup awscli - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - sudo unzip -q awscliv2.zip - sudo ./aws/install - shell: bash - - - name: Publish RPMs to standard repositories - run: | - FILES="*.rpm" - - REPOTYPE="${{ inputs.stability }}" - PROJECT_PATH="standard" - DISTRIB="${{ inputs.distrib }}" - ARCH="noarch" - - eval `ssh-agent` - ssh-add - <<< "${{ inputs.yum_repo_key }}" - - for MAJOR in "21.10" "22.04" "22.10"; do - echo "::group::Delivering to $MAJOR $REPOTYPE" - - if [ "$REPOTYPE" == "stable" ]; then - TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/RPMS" - else - TARGET="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/${{ inputs.module_name }}" - PROJECT_LOCATION="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/${{ inputs.module_name }}" - fi - - echo "[DEBUG] - Target : $TARGET" - echo "[DEBUG] - PROJECT_LOCATION : $PROJECT_LOCATION" - - ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" mkdir -p "$TARGET" - scp -o StrictHostKeyChecking=no ./*.rpm "${{ inputs.yum_repo_address }}:$TARGET" - - # Update repository metadata - METADATAS="/srv/centreon-yum/yum.centreon.com/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH" - ssh -o StrictHostKeyChecking=no "${{ inputs.yum_repo_address }}" "sh "${{ inputs.update_repo_path }}" $METADATAS" 2>&- - - # Invalidate cloudfront cache - ID="${{ inputs.cloudfront_id }}" - PATHS="/$PROJECT_PATH/$MAJOR/$DISTRIB/$REPOTYPE/$ARCH/*" - ITERATIONS=1 - - until aws cloudfront create-invalidation --distribution-id "$ID" --paths "$PATHS"; do - if [ ${ITERATIONS} -eq 10 ]; then - return 0 - fi - echo "couldn't invalidate cache, AWS quota might have been reached, retrying in 30 seconds..." - sleep 30s - ITERATIONS=$((ITERATIONS+1)) - done - - echo "::endgroup::" - done - shell: bash diff --git a/.github/workflows/connector-vmware.yml b/.github/workflows/connector-vmware.yml index 03b21bae7..6afd589d3 100644 --- a/.github/workflows/connector-vmware.yml +++ b/.github/workflows/connector-vmware.yml @@ -75,10 +75,6 @@ jobs: module_name: connector-vmware distrib: ${{ matrix.distrib }} cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} - update_repo_path: ${{ secrets.UPDATE_REPO_PATH }} - cloudfront_id: ${{ secrets.CLOUDFRONT_ID }} - yum_repo_address: ${{ secrets.YUM_REPO_ADDRESS }} - yum_repo_key: ${{ secrets.YUM_REPO_KEY }} stability: ${{ needs.get-environment.outputs.stability }} artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} @@ -101,8 +97,6 @@ jobs: uses: ./.github/actions/deb-delivery with: distrib: ${{ matrix.distrib }} - nexus_username: ${{ secrets.NEXUS_USERNAME }} - nexus_password: ${{ secrets.NEXUS_PASSWORD }} cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} stability: ${{ needs.get-environment.outputs.stability }} artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} diff --git a/.github/workflows/perl-vmware-vsphere.yml b/.github/workflows/perl-vmware-vsphere.yml index c4bc51aae..be2485f30 100644 --- a/.github/workflows/perl-vmware-vsphere.yml +++ b/.github/workflows/perl-vmware-vsphere.yml @@ -95,10 +95,6 @@ jobs: module_name: perl-vmware-vsphere distrib: ${{ matrix.distrib }} cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} - update_repo_path: ${{ secrets.UPDATE_REPO_PATH }} - cloudfront_id: ${{ secrets.CLOUDFRONT_ID }} - yum_repo_address: ${{ secrets.YUM_REPO_ADDRESS }} - yum_repo_key: ${{ secrets.YUM_REPO_KEY }} stability: ${{ needs.get-environment.outputs.stability }} artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} @@ -121,8 +117,6 @@ jobs: uses: ./.github/actions/deb-delivery with: distrib: ${{ matrix.distrib }} - nexus_username: ${{ secrets.NEXUS_USERNAME }} - nexus_password: ${{ secrets.NEXUS_PASSWORD }} cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} stability: ${{ needs.get-environment.outputs.stability }} artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} diff --git a/.github/workflows/plugin-delivery.yml b/.github/workflows/plugin-delivery.yml index 66fbc7541..d0a0226d7 100644 --- a/.github/workflows/plugin-delivery.yml +++ b/.github/workflows/plugin-delivery.yml @@ -77,12 +77,32 @@ jobs: module_name: plugins distrib: ${{ matrix.distrib }} cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} + stability: ${{ inputs.stability }} + artifactory_token: ${{ secrets.artifactory_token }} + + deliver-rpm-legacy: + runs-on: [self-hosted, common] + strategy: + matrix: + distrib: [el7, el8] + major_version: ["21.10", "22.04", "22.10"] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Delivery + uses: ./.github/actions/rpm-delivery-legacy + with: + module_name: plugins + major_version: ${{ matrix.major_version }} + distrib: ${{ matrix.distrib }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} update_repo_path: ${{ secrets.update_repo_path }} cloudfront_id: ${{ secrets.cloudfront_id }} yum_repo_address: ${{ secrets.yum_repo_address }} yum_repo_key: ${{ secrets.yum_repo_key }} stability: ${{ inputs.stability }} - artifactory_token: ${{ secrets.artifactory_token }} deliver-deb: runs-on: [self-hosted, common] @@ -98,8 +118,27 @@ jobs: uses: ./.github/actions/deb-delivery with: distrib: ${{ matrix.distrib }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} + stability: ${{ inputs.stability }} + artifactory_token: ${{ secrets.artifactory_token }} + + deliver-deb-legacy: + runs-on: [self-hosted, common] + strategy: + matrix: + distrib: [bullseye] + major_version: ["22.04", "22.10"] + + steps: + - name: Checkout sources + uses: actions/checkout@v3 + + - name: Delivery + uses: ./.github/actions/deb-delivery-legacy + with: + distrib: ${{ matrix.distrib }} + major_version: ${{ matrix.major_version }} nexus_username: ${{ secrets.nexus_username }} nexus_password: ${{ secrets.nexus_password }} cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} stability: ${{ inputs.stability }} - artifactory_token: ${{ secrets.artifactory_token }} diff --git a/.github/workflows/plugin-package.yml b/.github/workflows/plugin-package.yml index 81bade299..9a75f5fe4 100644 --- a/.github/workflows/plugin-package.yml +++ b/.github/workflows/plugin-package.yml @@ -19,9 +19,6 @@ on: jobs: fatpacker: runs-on: ubuntu-22.04 - outputs: - version: ${{ steps.get_version.outputs.version }} - release: ${{ steps.get_version.outputs.release }} steps: - name: Checkout sources uses: actions/checkout@v3 @@ -29,17 +26,16 @@ jobs: fetch-depth: 1 - name: Prepare FatPacker - uses: perl-actions/install-with-cpm@stable + uses: shogo82148/actions-setup-perl@v1 with: - install: | - App::FatPacker - File::Copy::Recursive - JSON + perl-version: '5.34' + install-modules-with: cpm + install-modules: App::FatPacker File::Copy::Recursive JSON - name: Run FatPacker run: | COMMIT=$(git log -1 HEAD --pretty=format:%h) - perl .github/scripts/plugins-source.container.pl "${{ inputs.plugins }}" "${{ steps.get_version.outputs.version }} ($COMMIT)" + perl .github/scripts/plugins-source.container.pl "${{ inputs.plugins }}" "${{ inputs.version }} ($COMMIT)" - uses: actions/cache@v3 with: diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 850d3c166..6af13d3d1 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -55,19 +55,17 @@ jobs: - name: transform to directories run: | folders=() - for f in ${{ steps.filter.outputs.packages_files }}; \ - do \ - echo "Adding $(dirname $f) to folders"; \ - folders+=($(dirname $f)); \ + for f in ${{ steps.filter.outputs.packages_files }}; do + echo "Adding $(dirname $f) to folders" + folders+=($(dirname $f)) done unique_folders=($(printf "%s\n" "${folders[@]}" | sort -u | tr '\n' ' ')) jq --compact-output --null-input '$ARGS.positional' --args -- ${unique_folders[@]} > package_directories.txt files=() - for f in ${{ steps.filter.outputs.plugins_files }}; \ - do \ - echo "Adding $f to files"; \ - files+=($f); \ + for f in ${{ steps.filter.outputs.plugins_files }}; do + echo "Adding $f to files" + files+=($f) done unique_files=($(printf "%s\n" "${files[@]}" | sort -u | tr '\n' ' ')) jq --compact-output --null-input '$ARGS.positional' --args -- ${unique_files[@]} > plugins.txt From cda29fb7c41e2a96f03326c478a58484e674af71 Mon Sep 17 00:00:00 2001 From: itoussies <65223458+itoussies@users.noreply.github.com> Date: Thu, 1 Jun 2023 09:47:59 +0200 Subject: [PATCH 436/447] apps::protocol::x509 - opensslcli custom mode - fix usage --- packaging/centreon-plugin-Applications-Protocol-X509/pkg.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/centreon-plugin-Applications-Protocol-X509/pkg.json b/packaging/centreon-plugin-Applications-Protocol-X509/pkg.json index 1fdcba204..3cf469628 100644 --- a/packaging/centreon-plugin-Applications-Protocol-X509/pkg.json +++ b/packaging/centreon-plugin-Applications-Protocol-X509/pkg.json @@ -4,6 +4,8 @@ "plugin_name": "centreon_protocol_x509.pl", "files": [ "centreon/plugins/script_custom.pm", + "centreon/plugins/backend/ssh/", + "centreon/plugins/ssh.pm", "apps/protocols/x509/" ] } From 722bee323689ba8e6baed0e42a038b3c340503d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Duret?= Date: Fri, 2 Jun 2023 08:53:38 +0200 Subject: [PATCH 437/447] apps::monitoring::iplabel::newtest::restapi - mode scenarios - fix options (#4435) --- .../iplabel/newtest/restapi/mode/scenarios.pm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/apps/monitoring/iplabel/newtest/restapi/mode/scenarios.pm b/src/apps/monitoring/iplabel/newtest/restapi/mode/scenarios.pm index 02ef7c036..e47e76b7f 100644 --- a/src/apps/monitoring/iplabel/newtest/restapi/mode/scenarios.pm +++ b/src/apps/monitoring/iplabel/newtest/restapi/mode/scenarios.pm @@ -291,14 +291,18 @@ Check scenarios. =over 8 -=item B<--filter-node-id> +=item B<--filter-robot-name> -Filter nodes (can be a regexp). +Filter robots (can be a regexp). + +=item B<--filter-scenario-name> + +Filter scenarios (can be a regexp). =item B<--warning-*> B<--critical-*> Thresholds. -Can be: 'ping-received-lasttime' (s). +Can be: 'status-green', 'status-red', 'status-orange', 'status-grey', 'execution-time'. =back From fb87a462a23b7bb834875f0ca3b5c4cdef0b4cdd Mon Sep 17 00:00:00 2001 From: omercier <32134301+omercier@users.noreply.github.com> Date: Fri, 2 Jun 2023 10:07:11 +0200 Subject: [PATCH 438/447] Fixing typos and improving help for some options (#4433) --- doc/en/user/guide.rst | 2 +- .../clamav/local/mode/updatestatus.pm | 12 ++--- .../automation/ansible/tower/mode/hosts.pm | 6 +-- .../ansible/tower/mode/jobtemplates.pm | 6 +-- .../ansible/tower/mode/schedules.pm | 6 +-- .../arcserve/udp/mssql/mode/jobstatus.pm | 6 +-- .../backup/backupexec/local/mode/alerts.pm | 4 +- .../backup/backupexec/local/mode/disks.pm | 4 +- src/apps/backup/backupexec/local/mode/jobs.pm | 8 ++-- .../commserve/restapi/mode/alerts.pm | 4 +- .../commvault/commserve/restapi/mode/jobs.pm | 8 ++-- .../commserve/restapi/mode/mediaagents.pm | 6 +-- .../commserve/restapi/mode/storagepools.pm | 6 +-- .../netapp/snapcenter/restapi/mode/jobs.pm | 6 +-- .../netbackup/local/mode/dedupstatus.pm | 4 +- .../netbackup/local/mode/drivestatus.pm | 4 +- .../backup/netbackup/local/mode/jobstatus.pm | 14 +++--- .../quadstor/local/mode/vtldiskusage.pm | 4 +- .../quadstor/local/mode/vtljobstatus.pm | 12 ++--- .../quadstor/local/mode/vtltapeusage.pm | 4 +- .../backup/rapidrecovery/snmp/mode/agent.pm | 6 +-- .../rapidrecovery/snmp/mode/repository.pm | 6 +-- .../backup/rubrik/restapi/mode/cluster.pm | 6 +-- src/apps/backup/rubrik/restapi/mode/disks.pm | 6 +-- src/apps/backup/rubrik/restapi/mode/nodes.pm | 6 +-- src/apps/backup/tsm/local/mode/actlog.pm | 4 +- src/apps/backup/tsm/local/mode/sessions.pm | 4 +- src/apps/backup/veeam/local/mode/jobstatus.pm | 10 ++-- src/apps/backup/veeam/local/mode/licenses.pm | 4 +- .../backup/veeam/local/mode/repositories.pm | 4 +- src/apps/backup/veeam/local/mode/tapejobs.pm | 6 +-- src/apps/backup/veeam/local/mode/vsbjobs.pm | 6 +-- src/apps/centreon/local/mode/brokerstats.pm | 4 +- src/apps/ceph/restapi/mode/health.pm | 4 +- src/apps/cisco/cms/restapi/mode/alarms.pm | 4 +- src/apps/cisco/ssms/restapi/mode/licenses.pm | 6 +-- src/apps/controlm/restapi/mode/jobs.pm | 8 ++-- src/apps/emc/ppma/restapi/mode/hosts.pm | 6 +-- src/apps/ericsson/enm/api/mode/nodes.pm | 18 +++---- src/apps/grafana/api/mode/health.pm | 4 +- src/apps/haproxy/snmp/mode/backendusage.pm | 4 +- src/apps/haproxy/snmp/mode/frontendusage.pm | 4 +- src/apps/hddtemp/mode/temperatures.pm | 6 +-- .../ibm/tsamp/local/mode/resourcegroups.pm | 6 +-- src/apps/inin/ig/snmp/mode/spanusage.pm | 4 +- .../inin/mediaserver/snmp/mode/cmdsrvusage.pm | 4 +- src/apps/java/awa/jmx/mode/agent.pm | 4 +- src/apps/java/awa/jmx/mode/queue.pm | 4 +- src/apps/java/awa/jmx/mode/server.pm | 4 +- src/apps/keepalived/snmp/mode/vrrpstatus.pm | 4 +- src/apps/microsoft/dhcp/snmp/mode/subnets.pm | 6 +-- .../exchange/local/mode/activesyncmailbox.pm | 4 +- .../exchange/local/mode/databases.pm | 16 +++---- .../exchange/local/mode/imapmailbox.pm | 4 +- .../exchange/local/mode/mapimailbox.pm | 4 +- .../exchange/local/mode/outlookwebservices.pm | 4 +- .../exchange/local/mode/owamailbox.pm | 4 +- .../microsoft/exchange/local/mode/queues.pm | 4 +- .../exchange/local/mode/replicationhealth.pm | 4 +- .../microsoft/exchange/local/mode/services.pm | 4 +- .../2012/local/mode/nodeintegrationservice.pm | 8 ++-- .../hyperv/2012/local/mode/nodereplication.pm | 4 +- .../hyperv/2012/local/mode/nodevmstatus.pm | 4 +- .../local/mode/scvmmintegrationservice.pm | 4 +- .../hyperv/2012/local/mode/scvmmvmstatus.pm | 4 +- .../iis/local/mode/applicationpoolstate.pm | 6 +-- .../iis/restapi/mode/applicationpools.pm | 6 +-- .../microsoft/iis/restapi/mode/websites.pm | 6 +-- .../iis/wsman/mode/applicationpools.pm | 6 +-- .../mscs/local/mode/networkstatus.pm | 6 +-- .../microsoft/mscs/local/mode/nodestatus.pm | 6 +-- .../mscs/local/mode/resourcegroupstatus.pm | 6 +-- .../mscs/local/mode/resourcestatus.pm | 6 +-- .../local/mode/databasereplicationstatus.pm | 8 ++-- .../microsoft/sccm/local/mode/sitestatus.pm | 4 +- .../wsus/local/mode/synchronisationstatus.pm | 8 ++-- .../iplabel/datametrie/restapi/mode/kpi.pm | 6 +-- .../monitoring/mip/restapi/mode/scenarios.pm | 8 ++-- .../nodeexporter/windows/mode/services.pm | 4 +- .../monitoring/ntopng/restapi/mode/alerts.pm | 4 +- .../monitoring/scom/restapi/mode/alerts.pm | 4 +- src/apps/mq/activemq/jmx/mode/brokers.pm | 4 +- src/apps/mq/ibmmq/mqi/mode/channels.pm | 6 +-- src/apps/mq/ibmmq/mqi/mode/queuemanager.pm | 6 +-- .../mq/ibmmq/restapi/mode/queuemanagers.pm | 6 +-- .../mq/rabbitmq/restapi/mode/nodeusage.pm | 4 +- .../mq/rabbitmq/restapi/mode/queueusage.pm | 4 +- .../mq/rabbitmq/restapi/mode/vhostusage.pm | 4 +- src/apps/mq/vernemq/restapi/mode/clusters.pm | 6 +-- src/apps/mq/vernemq/restapi/mode/listeners.pm | 6 +-- .../restapi/mode/cityweather.pm | 4 +- src/apps/oracle/gg/local/mode/processes.pm | 6 +-- src/apps/oracle/ovm/api/mode/manager.pm | 6 +-- src/apps/oracle/ovm/api/mode/servers.pm | 6 +-- src/apps/oracle/ovm/api/mode/vm.pm | 6 +-- src/apps/pacemaker/local/mode/crm.pm | 16 +++---- src/apps/pfsense/fauxapi/mode/gateways.pm | 6 +-- .../pineapp/securemail/snmp/mode/system.pm | 12 ++--- src/apps/protocols/cifs/mode/connection.pm | 4 +- src/apps/protocols/cifs/mode/scenario.pm | 8 ++-- .../protocols/http/mode/expectedcontent.pm | 6 +-- src/apps/protocols/http/mode/jsoncontent.pm | 13 +++-- src/apps/protocols/http/mode/soapcontent.pm | 10 ++-- src/apps/protocols/ospf/snmp/mode/neighbor.pm | 4 +- src/apps/protocols/radius/mode/login.pm | 4 +- src/apps/protocols/sftp/mode/connection.pm | 4 +- src/apps/protocols/sftp/mode/scenario.pm | 8 ++-- src/apps/protocols/ssh/mode/login.pm | 4 +- .../protocols/tcp/mode/connectionstatus.pm | 6 +-- src/apps/protocols/tftp/mode/commands.pm | 4 +- src/apps/protocols/whois/mode/domain.pm | 6 +-- src/apps/proxmox/mg/restapi/mode/version.pm | 4 +- src/apps/proxmox/ve/restapi/mode/nodeusage.pm | 4 +- .../proxmox/ve/restapi/mode/storageusage.pm | 4 +- src/apps/proxmox/ve/restapi/mode/vmusage.pm | 4 +- .../redis/rlec/restapi/mode/databasesstats.pm | 4 +- .../redis/rlec/restapi/mode/nodesstats.pm | 4 +- .../redis/rlec/restapi/mode/shardsstats.pm | 4 +- src/apps/redis/sentinel/mode/redisclusters.pm | 6 +-- .../redis/sentinel/mode/sentinelclusters.pm | 12 ++--- .../rudder/restapi/mode/globalcompliance.pm | 4 +- .../rudder/restapi/mode/nodecompliance.pm | 4 +- .../rudder/restapi/mode/rulecompliance.pm | 4 +- src/apps/sahipro/restapi/mode/scenario.pm | 4 +- src/apps/smartermail/restapi/mode/licenses.pm | 6 +-- src/apps/smartermail/restapi/mode/services.pm | 6 +-- .../mistral/vs9/restapi/mode/clusters.pm | 12 ++--- .../mistral/vs9/restapi/mode/devices.pm | 48 +++++++++---------- .../vs9/restapi/mode/mmccertificates.pm | 6 +-- .../mistral/vs9/restapi/mode/mmccluster.pm | 12 ++--- src/apps/tomcat/web/mode/applications.pm | 6 +-- .../storemate/sql/mode/maintenanceplan.pm | 4 +- .../video/openheadend/snmp/mode/nodeusage.pm | 4 +- .../openheadend/snmp/mode/operationstatus.pm | 4 +- .../restapi/mode/broadcasterinputusage.pm | 4 +- .../restapi/mode/broadcasterlicenseusage.pm | 4 +- .../restapi/mode/broadcasteroutputusage.pm | 4 +- .../zixi/restapi/mode/feederinputusage.pm | 4 +- .../zixi/restapi/mode/feederoutputusage.pm | 4 +- .../hpe/simplivity/restapi/mode/hosts.pm | 24 +++++----- .../restapi/mode/virtualmachines.pm | 6 +-- src/apps/vmware/connector/custom/connector.pm | 6 +-- .../vmware/connector/mode/alarmdatacenter.pm | 4 +- src/apps/vmware/connector/mode/alarmhost.pm | 4 +- src/apps/vmware/connector/mode/countvmhost.pm | 6 +-- src/apps/vmware/connector/mode/cpuhost.pm | 6 +-- src/apps/vmware/connector/mode/cpuvm.pm | 6 +-- .../vmware/connector/mode/datastorecountvm.pm | 6 +-- .../vmware/connector/mode/datastorehost.pm | 6 +-- src/apps/vmware/connector/mode/datastoreio.pm | 6 +-- .../vmware/connector/mode/datastoreiops.pm | 6 +-- .../connector/mode/datastoresnapshot.pm | 6 +-- .../vmware/connector/mode/datastoreusage.pm | 6 +-- src/apps/vmware/connector/mode/datastorevm.pm | 6 +-- src/apps/vmware/connector/mode/devicevm.pm | 6 +-- src/apps/vmware/connector/mode/healthhost.pm | 6 +-- src/apps/vmware/connector/mode/limitvm.pm | 12 ++--- .../vmware/connector/mode/maintenancehost.pm | 10 ++-- src/apps/vmware/connector/mode/memoryhost.pm | 6 +-- src/apps/vmware/connector/mode/memoryvm.pm | 6 +-- src/apps/vmware/connector/mode/nethost.pm | 12 ++--- src/apps/vmware/connector/mode/netvm.pm | 6 +-- src/apps/vmware/connector/mode/servicehost.pm | 10 ++-- .../vmware/connector/mode/statuscluster.pm | 6 +-- src/apps/vmware/connector/mode/statushost.pm | 12 ++--- src/apps/vmware/connector/mode/statusvm.pm | 12 ++--- src/apps/vmware/connector/mode/storagehost.pm | 18 +++---- src/apps/vmware/connector/mode/swaphost.pm | 6 +-- src/apps/vmware/connector/mode/swapvm.pm | 6 +-- src/apps/vmware/connector/mode/timehost.pm | 6 +-- src/apps/vmware/connector/mode/uptimehost.pm | 6 +-- src/apps/vmware/vcsa/restapi/mode/health.pm | 6 +-- src/apps/vmware/vcsa/snmp/mode/interfaces.pm | 4 +- src/apps/voip/3cx/restapi/mode/extension.pm | 6 +-- src/apps/voip/3cx/restapi/mode/system.pm | 6 +-- .../voip/asterisk/ami/mode/dahdistatus.pm | 4 +- .../voip/asterisk/ami/mode/sippeersusage.pm | 4 +- src/apps/vtom/restapi/mode/jobs.pm | 8 ++-- src/apps/wallix/bastion/snmp/mode/license.pm | 4 +- src/apps/wallix/bastion/snmp/mode/system.pm | 4 +- src/apps/wazuh/restapi/mode/agents.pm | 4 +- src/apps/wazuh/restapi/mode/manager.pm | 4 +- .../common/airespace/snmp/mode/apstatus.pm | 8 ++-- .../common/bluearc/snmp/mode/clusterstatus.pm | 6 +-- .../common/bluearc/snmp/mode/interfaces.pm | 4 +- .../common/bluearc/snmp/mode/volumeusage.pm | 4 +- .../cisco/ironport/snmp/mode/mailusage.pm | 6 +-- .../cisco/ironport/xmlapi/mode/systemusage.pm | 4 +- .../cisco/standard/snmp/mode/aaaservers.pm | 6 +-- .../common/cisco/standard/snmp/mode/bgp.pm | 6 +-- .../cisco/standard/snmp/mode/configuration.pm | 4 +- .../cisco/standard/snmp/mode/interfaces.pm | 4 +- .../cisco/standard/snmp/mode/memoryflash.pm | 6 +-- .../cisco/standard/snmp/mode/qosusage.pm | 2 +- .../common/cisco/standard/snmp/mode/stack.pm | 8 ++-- .../common/cisco/standard/snmp/mode/vpc.pm | 18 +++---- .../common/cisco/standard/snmp/mode/vss.pm | 18 +++---- .../common/cisco/standard/snmp/mode/wan3g.pm | 30 ++++++------ .../common/cps/ups/snmp/mode/batterystatus.pm | 6 +-- .../common/cps/ups/snmp/mode/inputlines.pm | 6 +-- .../common/cps/ups/snmp/mode/outputlines.pm | 6 +-- .../common/emc/navisphere/mode/hbastate.pm | 4 +- .../fortinet/fortigate/snmp/mode/apusage.pm | 6 +-- .../fortigate/snmp/mode/clusterstatus.pm | 4 +- .../fortigate/snmp/mode/interfaces.pm | 4 +- .../fortinet/fortigate/snmp/mode/sdwan.pm | 6 +-- .../fortinet/fortigate/snmp/mode/vdomusage.pm | 4 +- .../common/h3c/snmp/mode/interfaces.pm | 4 +- .../riverbed/steelhead/snmp/mode/status.pm | 4 +- .../common/xppc/snmp/mode/batterystatus.pm | 6 +-- .../common/xppc/snmp/mode/outputlines.pm | 6 +-- src/centreon/plugins/http.pm | 4 +- src/centreon/plugins/output.pm | 47 +++++++++++------- src/centreon/plugins/script.pm | 5 +- src/centreon/plugins/script_custom.pm | 18 +++---- src/centreon/plugins/script_simple.pm | 11 +++-- src/centreon/plugins/script_snmp.pm | 11 +++-- src/centreon/plugins/script_sql.pm | 11 +++-- src/centreon/plugins/script_wsman.pm | 11 +++-- src/centreon/plugins/statefile.pm | 2 +- src/cloud/aws/apigateway/mode/latency.pm | 2 +- src/cloud/aws/apigateway/mode/requests.pm | 2 +- .../aws/billing/mode/estimatedcharges.pm | 2 +- src/cloud/aws/cloudfront/mode/errors.pm | 2 +- src/cloud/aws/cloudfront/mode/requests.pm | 2 +- src/cloud/aws/cloudfront/mode/throughput.pm | 2 +- src/cloud/aws/cloudwatch/mode/getalarms.pm | 4 +- src/cloud/aws/cloudwatchlogs/mode/getlogs.pm | 6 +-- src/cloud/aws/custom/awscli.pm | 2 +- src/cloud/aws/custom/paws.pm | 2 +- .../aws/directconnect/mode/connections.pm | 4 +- .../directconnect/mode/virtualinterfaces.pm | 4 +- src/cloud/aws/ec2/mode/cpu.pm | 2 +- src/cloud/aws/ec2/mode/diskio.pm | 2 +- src/cloud/aws/ec2/mode/instancesstatus.pm | 4 +- src/cloud/aws/ec2/mode/network.pm | 2 +- src/cloud/aws/ec2/mode/status.pm | 6 +-- src/cloud/aws/efs/mode/connections.pm | 2 +- src/cloud/aws/efs/mode/datausage.pm | 2 +- .../aws/elasticache/mode/commandsmemcached.pm | 2 +- .../aws/elasticache/mode/commandsredis.pm | 2 +- src/cloud/aws/elasticache/mode/connections.pm | 2 +- src/cloud/aws/elasticache/mode/cpu.pm | 2 +- src/cloud/aws/elasticache/mode/evictions.pm | 2 +- src/cloud/aws/elasticache/mode/items.pm | 2 +- src/cloud/aws/elasticache/mode/network.pm | 2 +- src/cloud/aws/elasticache/mode/replication.pm | 2 +- .../aws/elasticache/mode/requestsmemcached.pm | 2 +- .../aws/elasticache/mode/requestsredis.pm | 2 +- .../aws/elasticache/mode/usagememcached.pm | 2 +- src/cloud/aws/elasticache/mode/usageredis.pm | 2 +- .../aws/elb/application/mode/connections.pm | 4 +- .../aws/elb/application/mode/httpcodes.pm | 4 +- .../aws/elb/application/mode/targetshealth.pm | 4 +- src/cloud/aws/elb/classic/mode/httpcodes.pm | 4 +- .../aws/elb/classic/mode/performances.pm | 4 +- src/cloud/aws/elb/classic/mode/queues.pm | 4 +- .../aws/elb/classic/mode/targetshealth.pm | 4 +- .../aws/elb/network/mode/targetshealth.pm | 4 +- src/cloud/aws/fsx/mode/datausage.pm | 2 +- src/cloud/aws/fsx/mode/freespace.pm | 2 +- src/cloud/aws/kinesis/mode/recordsstats.pm | 2 +- src/cloud/aws/kinesis/mode/streams.pm | 2 +- src/cloud/aws/lambda/mode/invocations.pm | 2 +- src/cloud/aws/rds/mode/connections.pm | 2 +- src/cloud/aws/rds/mode/cpu.pm | 2 +- src/cloud/aws/rds/mode/diskio.pm | 2 +- src/cloud/aws/rds/mode/instancestatus.pm | 4 +- src/cloud/aws/rds/mode/network.pm | 2 +- src/cloud/aws/rds/mode/queries.pm | 2 +- src/cloud/aws/rds/mode/storage.pm | 2 +- src/cloud/aws/rds/mode/transactions.pm | 2 +- src/cloud/aws/rds/mode/volume.pm | 2 +- src/cloud/aws/s3/mode/bucketsize.pm | 4 +- src/cloud/aws/s3/mode/objects.pm | 2 +- src/cloud/aws/s3/mode/requests.pm | 2 +- src/cloud/aws/ses/mode/emails.pm | 2 +- .../azure/analytics/eventhubs/mode/health.pm | 8 ++-- .../azure/common/storageaccount/health.pm | 10 ++-- src/cloud/azure/compute/aks/mode/health.pm | 10 ++-- .../compute/virtualmachine/mode/health.pm | 10 ++-- .../azure/compute/vmscalesets/mode/health.pm | 10 ++-- src/cloud/azure/custom/api.pm | 12 +++-- src/cloud/azure/custom/azcli.pm | 8 ++-- .../azure/database/cosmosdb/mode/health.pm | 8 ++-- src/cloud/azure/database/redis/mode/health.pm | 8 ++-- .../azure/database/sqldatabase/mode/health.pm | 8 ++-- .../database/sqlserver/mode/serverstatus.pm | 4 +- .../integration/eventgrid/mode/health.pm | 8 ++-- .../integration/servicebus/mode/health.pm | 10 ++-- .../management/monitor/mode/getmetrics.pm | 2 +- .../azure/management/monitor/mode/health.pm | 2 +- .../recovery/mode/backupitemsstatus.pm | 4 +- .../recovery/mode/backupjobsstatus.pm | 4 +- .../recovery/mode/replicationhealth.pm | 8 ++-- .../resource/mode/deploymentsstatus.pm | 4 +- .../azure/network/appgateway/mode/health.pm | 8 ++-- .../expressroute/mode/circuitstatus.pm | 4 +- .../azure/network/expressroute/mode/health.pm | 10 ++-- .../virtualnetwork/mode/peeringsstatus.pm | 4 +- .../azure/network/vpngateway/mode/health.pm | 10 ++-- .../vpngateway/mode/vpngatewaystatus.pm | 4 +- .../azure/web/appserviceplan/mode/health.pm | 8 ++-- src/cloud/azure/web/signalr/mode/health.pm | 8 ++-- .../docker/restapi/mode/containerusage.pm | 4 +- src/cloud/docker/restapi/mode/nodestatus.pm | 4 +- .../docker/restapi/mode/servicestatus.pm | 6 +-- .../google/gcp/cloudsql/common/mode/cpu.pm | 4 +- .../gcp/cloudsql/common/mode/network.pm | 4 +- .../gcp/cloudsql/common/mode/storage.pm | 4 +- .../google/gcp/cloudsql/mysql/mode/innodb.pm | 4 +- .../google/gcp/cloudsql/mysql/mode/queries.pm | 4 +- .../gcp/compute/computeengine/mode/cpu.pm | 4 +- .../gcp/compute/computeengine/mode/diskio.pm | 4 +- .../gcp/compute/computeengine/mode/network.pm | 4 +- src/cloud/google/gcp/custom/api.pm | 4 +- .../management/stackdriver/mode/getmetrics.pm | 6 ++- src/cloud/google/gcp/storage/mode/bucket.pm | 4 +- src/cloud/ibm/softlayer/mode/events.pm | 4 +- src/cloud/ibm/softlayer/mode/opentickets.pm | 4 +- src/cloud/iics/restapi/mode/agents.pm | 12 ++--- src/cloud/kubernetes/mode/cronjobstatus.pm | 4 +- src/cloud/kubernetes/mode/daemonsetstatus.pm | 4 +- src/cloud/kubernetes/mode/deploymentstatus.pm | 4 +- src/cloud/kubernetes/mode/nodestatus.pm | 4 +- .../kubernetes/mode/persistentvolumestatus.pm | 4 +- src/cloud/kubernetes/mode/podstatus.pm | 10 ++-- src/cloud/kubernetes/mode/replicasetstatus.pm | 4 +- .../mode/replicationcontrollerstatus.pm | 4 +- .../kubernetes/mode/statefulsetstatus.pm | 4 +- .../microsoft/office365/custom/graphapi.pm | 2 +- .../office365/custom/managementapi.pm | 2 +- .../office365/exchange/mode/mailboxusage.pm | 4 +- .../management/mode/appcredentials.pm | 8 ++-- .../management/mode/servicestatus.pm | 4 +- .../management/mode/subscriptions.pm | 4 +- src/cloud/nutanix/snmp/mode/clusterusage.pm | 4 +- src/cloud/nutanix/snmp/mode/diskusage.pm | 4 +- src/cloud/nutanix/snmp/mode/vmusage.pm | 4 +- src/cloud/outscale/mode/clientgateways.pm | 6 +-- src/cloud/outscale/mode/internetservices.pm | 6 +-- src/cloud/outscale/mode/loadbalancers.pm | 6 +-- src/cloud/outscale/mode/natservices.pm | 6 +-- src/cloud/outscale/mode/nets.pm | 6 +-- src/cloud/outscale/mode/quotas.pm | 6 +-- src/cloud/outscale/mode/subnets.pm | 6 +-- src/cloud/outscale/mode/virtualgateways.pm | 6 +-- src/cloud/outscale/mode/vms.pm | 6 +-- src/cloud/outscale/mode/volumes.pm | 6 +-- src/cloud/outscale/mode/vpnconnections.pm | 6 +-- .../direct/kubernetes/mode/containerstatus.pm | 8 ++-- .../direct/kubernetes/mode/daemonsetstatus.pm | 8 ++-- .../kubernetes/mode/deploymentstatus.pm | 8 ++-- .../direct/kubernetes/mode/listcontainers.pm | 4 +- .../direct/kubernetes/mode/listdaemonsets.pm | 4 +- .../direct/kubernetes/mode/listdeployments.pm | 4 +- .../direct/kubernetes/mode/listnamespaces.pm | 4 +- .../direct/kubernetes/mode/listnodes.pm | 4 +- .../direct/kubernetes/mode/listservices.pm | 4 +- .../direct/kubernetes/mode/namespacestatus.pm | 8 ++-- .../direct/kubernetes/mode/nodestatus.pm | 8 ++-- .../mode/connections.pm | 4 +- .../nginxingresscontroller/mode/requests.pm | 4 +- .../prometheus/exporters/cadvisor/mode/cpu.pm | 4 +- .../exporters/cadvisor/mode/listcontainers.pm | 4 +- .../exporters/cadvisor/mode/load.pm | 4 +- .../exporters/cadvisor/mode/memory.pm | 4 +- .../exporters/cadvisor/mode/storage.pm | 4 +- .../exporters/cadvisor/mode/taskstate.pm | 4 +- .../exporters/nodeexporter/mode/cpu.pm | 4 +- .../nodeexporter/mode/cpudetailed.pm | 4 +- .../exporters/nodeexporter/mode/load.pm | 4 +- .../exporters/nodeexporter/mode/memory.pm | 4 +- .../exporters/nodeexporter/mode/storage.pm | 4 +- .../prometheus/restapi/mode/targetstatus.pm | 6 +-- src/cloud/talend/tmc/mode/plans.pm | 6 +-- src/cloud/talend/tmc/mode/remoteengines.pm | 6 +-- src/cloud/talend/tmc/mode/tasks.pm | 6 +-- .../velocloud/restapi/mode/edgestatus.pm | 6 +-- .../velocloud/restapi/mode/linkstatus.pm | 2 +- src/database/couchdb/restapi/mode/server.pm | 12 ++--- src/database/db2/mode/hadr.pm | 18 +++---- src/database/db2/mode/tablespaces.pm | 6 +-- .../restapi/mode/clusterstatistics.pm | 4 +- .../restapi/mode/indicestatistics.pm | 4 +- .../elasticsearch/restapi/mode/license.pm | 4 +- .../informix/snmp/mode/chunkstatus.pm | 6 +-- .../mongodb/mode/replicationstatus.pm | 8 ++-- src/database/mssql/mode/failedjobs.pm | 4 +- src/database/mysql/mode/backup.pm | 6 +-- src/database/mysql/mode/passwordexpiration.pm | 4 +- src/database/mysql/mode/replication.pm | 12 ++--- src/database/oracle/mode/asmdiskgroupusage.pm | 10 ++-- src/database/oracle/mode/datafilesstatus.pm | 8 ++-- src/database/oracle/mode/dataguard.pm | 6 +-- src/database/oracle/mode/longqueries.pm | 4 +- .../oracle/mode/passwordexpiration.pm | 4 +- src/database/redis/mode/persistence.pm | 4 +- src/database/redis/mode/replication.pm | 4 +- src/hardware/ats/apc/snmp/mode/outputlines.pm | 4 +- src/hardware/ats/eaton/snmp/mode/system.pm | 6 +-- .../devices/aeg/acm/snmp/mode/acstatus.pm | 4 +- .../aeg/acm/snmp/mode/batterystatus.pm | 4 +- .../aeg/acm/snmp/mode/rectifierstatus.pm | 4 +- .../devices/barco/cs/restapi/mode/device.pm | 8 ++-- .../cisco/ces/restapi/mode/diagnostics.pm | 4 +- .../cisco/cts/snmp/mode/peripherals.pm | 4 +- .../devices/eltek/enexus/snmp/mode/alarms.pm | 6 +-- .../devices/eltek/enexus/snmp/mode/battery.pm | 6 +-- .../devices/eltek/enexus/snmp/mode/load.pm | 6 +-- .../devices/eltek/enexus/snmp/mode/outputs.pm | 6 +-- .../gorgy/ntpserver/snmp/mode/globalstatus.pm | 8 ++-- .../devices/hikvision/nvr/isapi/mode/disks.pm | 6 +-- .../hikvision/nvr/isapi/mode/protocols.pm | 6 +-- .../devices/hikvision/nvr/snmp/mode/disks.pm | 6 +-- .../devices/hms/ewon/snmp/mode/tags.pm | 4 +- .../ntp100gps/snmp/mode/gpsstatus.pm | 4 +- .../ntp100gps/snmp/mode/ntpperformance.pm | 4 +- .../infinity/managementapi/mode/alarms.pm | 4 +- .../polycom/trio/restapi/mode/device.pm | 4 +- .../polycom/trio/restapi/mode/registration.pm | 4 +- .../tms6001/snmp/mode/antenna.pm | 6 +-- .../timelinkmicro/tms6001/snmp/mode/gnss.pm | 6 +-- .../video/appeartv/snmp/mode/alarms.pm | 4 +- .../kvm/adder/aim/snmp/mode/deviceusage.pm | 4 +- .../avocent/acs/8000/snmp/mode/serialports.pm | 6 +-- src/hardware/pdu/apc/snmp/mode/load.pm | 12 ++--- src/hardware/pdu/apc/snmp/mode/outlet.pm | 6 +-- src/hardware/pdu/cyberpower/snmp/mode/load.pm | 12 ++--- .../pdu/cyberpower/snmp/mode/outlets.pm | 6 +-- .../pdu/eaton/snmp/mode/environment.pm | 12 ++--- .../pdu/emerson/snmp/mode/globalstatus.pm | 6 +-- src/hardware/pdu/emerson/snmp/mode/psusage.pm | 2 +- .../pdu/emerson/snmp/mode/receptacles.pm | 6 +-- .../standard/rfc3805/mode/coverstatus.pm | 6 +-- .../server/cisco/ucs/snmp/mode/auditlogs.pm | 4 +- .../server/cisco/ucs/snmp/mode/faults.pm | 4 +- .../cisco/ucs/snmp/mode/mgmtentities.pm | 6 +-- .../cisco/ucs/snmp/mode/serviceprofile.pm | 4 +- .../dell/idrac/snmp/mode/globalstatus.pm | 12 ++--- .../server/dell/vxm/restapi/mode/chassis.pm | 12 ++--- .../server/dell/vxm/restapi/mode/hosts.pm | 18 +++---- .../hp/oneview/restapi/mode/storagepools.pm | 6 +-- .../server/ibm/hmc/ssh/mode/ledstatus.pm | 8 ++-- .../ibm/mgmt_cards/imm/snmp/mode/eventlog.pm | 4 +- .../telephony/avaya/aes/snmp/mode/services.pm | 12 ++--- .../telephony/avaya/cm/snmp/mode/trunks.pm | 6 +-- .../snmp/mode/controllerstatus.pm | 6 +-- .../ups/alpha/snmp/mode/batterystatus.pm | 6 +-- .../ups/apc/snmp/mode/batterystatus.pm | 18 +++---- src/hardware/ups/apc/snmp/mode/inputlines.pm | 4 +- src/hardware/ups/apc/snmp/mode/outputlines.pm | 6 +-- .../ups/hp/snmp/mode/batterystatus.pm | 6 +-- src/hardware/ups/hp/snmp/mode/outputlines.pm | 6 +-- src/hardware/ups/mge/snmp/mode/inputlines.pm | 4 +- .../ups/powerware/snmp/mode/batterystatus.pm | 6 +-- src/hardware/ups/riello/snmp/mode/battery.pm | 6 +-- .../ups/riello/snmp/mode/outputlines.pm | 6 +-- .../socomec/netvision/snmp/mode/battery.pm | 6 +-- .../netvision/snmp/mode/outputlines.pm | 6 +-- .../rfc1628/snmp/mode/batterystatus.pm | 6 +-- .../rfc1628/snmp/mode/outputsource.pm | 6 +-- src/network/a10/ax/snmp/mode/vserverusage.pm | 4 +- src/network/acmepacket/snmp/mode/sipusage.pm | 4 +- .../acmepacket/snmp/mode/systemusage.pm | 4 +- src/network/adva/fsp150/snmp/mode/alarms.pm | 4 +- src/network/adva/fsp3000/snmp/mode/alarms.pm | 4 +- .../adva/fsp3000/snmp/mode/interfaces.pm | 4 +- .../alcatel/isam/snmp/mode/hubsapusage.pm | 4 +- .../omniswitch/snmp/mode/virtualchassis.pm | 6 +-- src/network/alcatel/oxe/snmp/mode/trunks.pm | 4 +- .../alcatel/pss/1830/snmp/mode/sapqosstats.pm | 4 +- src/network/aruba/aoscx/restapi/mode/vsx.pm | 18 +++---- src/network/aruba/aoscx/snmp/mode/vsf.pm | 12 ++--- src/network/aruba/aoscx/snmp/mode/vsx.pm | 18 +++---- .../aruba/cppm/snmp/mode/interfaces.pm | 4 +- .../aruba/instant/snmp/mode/apusage.pm | 4 +- .../aruba/instant/snmp/mode/ssidstatus.pm | 4 +- .../aruba/orchestrator/restapi/mode/alarms.pm | 4 +- .../orchestrator/restapi/mode/appliances.pm | 6 +-- .../epc/snmp/mode/interfacesdiameter.pm | 12 ++--- .../athonet/epc/snmp/mode/interfacesga.pm | 6 +-- .../athonet/epc/snmp/mode/interfacesgtpc.pm | 6 +-- .../athonet/epc/snmp/mode/interfaceslte.pm | 6 +-- src/network/atrica/snmp/mode/connections.pm | 4 +- .../atto/fibrebridge/snmp/mode/fcportusage.pm | 4 +- .../audiocodes/snmp/mode/trunkstatus.pm | 4 +- .../cloudgen/snmp/mode/boxservice.pm | 4 +- .../cloudgen/snmp/mode/serverservice.pm | 4 +- .../barracuda/cloudgen/snmp/mode/vpnstatus.pm | 4 +- .../beeware/snmp/mode/reverseproxyusage.pm | 4 +- src/network/brocade/snmp/mode/interfaces.pm | 4 +- .../cambium/epmp/snmp/mode/interfaces.pm | 4 +- src/network/cambium/epmp/snmp/mode/license.pm | 6 +-- src/network/checkpoint/snmp/mode/rausers.pm | 4 +- src/network/checkpoint/snmp/mode/vpnstatus.pm | 4 +- .../cisco/aci/apic/restapi/mode/fabric.pm | 4 +- .../cisco/aci/apic/restapi/mode/tenant.pm | 4 +- src/network/cisco/asa/snmp/mode/failover.pm | 4 +- .../cisco/callmanager/snmp/mode/ccmusage.pm | 4 +- .../cisco/callmanager/snmp/mode/ctiusage.pm | 4 +- .../callmanager/snmp/mode/gatewayusage.pm | 4 +- .../callmanager/snmp/mode/mediadeviceusage.pm | 4 +- .../cisco/callmanager/snmp/mode/phoneusage.pm | 4 +- .../callmanager/snmp/mode/voicemailusage.pm | 4 +- .../cisco/callmanager/sxml/mode/services.pm | 6 +-- .../firepower/fmc/restapi/mode/devices.pm | 6 +-- .../cisco/firepower/fxos/snmp/mode/faults.pm | 4 +- .../cloudcontroller/restapi/mode/devices.pm | 18 +++---- .../cloudcontroller/snmp/mode/deviceusage.pm | 4 +- .../cisco/prime/restapi/mode/apusage.pm | 4 +- .../cisco/standard/ssh/mode/voicedialpeer.pm | 6 +-- .../cisco/umbrella/snmp/mode/appliance.pm | 4 +- .../wap/snmp/mode/virtualaccesspoints.pm | 6 +-- src/network/citrix/sdx/snmp/mode/srusage.pm | 4 +- src/network/colubris/snmp/mode/apusage.pm | 4 +- .../dell/nseries/snmp/mode/interfaces.pm | 4 +- src/network/denyall/snmp/mode/reverseproxy.pm | 6 +-- src/network/digi/sarian/snmp/mode/gprs.pm | 4 +- .../dlink/standard/snmp/mode/interfaces.pm | 4 +- src/network/dlink/standard/snmp/mode/stack.pm | 12 ++--- src/network/enterasys/snmp/mode/interfaces.pm | 4 +- .../evertz/AEA47721/snmp/mode/streamstatus.pm | 8 ++-- .../DA6HDL7700/snmp/mode/videostatus.pm | 4 +- src/network/extreme/snmp/mode/interfaces.pm | 4 +- src/network/extreme/snmp/mode/stack.pm | 12 ++--- src/network/f5/bigip/snmp/mode/failover.pm | 8 ++-- src/network/f5/bigip/snmp/mode/nodestatus.pm | 6 +-- src/network/f5/bigip/snmp/mode/poolstatus.pm | 12 ++--- src/network/f5/bigip/snmp/mode/trunks.pm | 12 ++--- .../f5/bigip/snmp/mode/virtualserverstatus.pm | 6 +-- .../fortinet/fortiadc/snmp/mode/interfaces.pm | 4 +- .../fortinet/fortiadc/snmp/mode/security.pm | 4 +- .../fortiadc/snmp/mode/virtualservers.pm | 6 +-- .../fortiauthenticator/snmp/mode/ha.pm | 4 +- .../fortinet/fortigate/restapi/mode/health.pm | 6 +-- .../fortigate/restapi/mode/licenses.pm | 4 +- .../fortimanager/snmp/mode/devicestatus.pm | 20 ++++---- .../fortiswitch/snmp/mode/interfaces.pm | 4 +- .../fortinet/fortiweb/snmp/mode/system.pm | 4 +- src/network/freebox/restapi/mode/system.pm | 8 ++-- .../standard/snmp/mode/configuration.pm | 4 +- .../hp/moonshot/snmp/mode/interfaces.pm | 4 +- .../hp/procurve/snmp/mode/interfaces.pm | 8 ++-- .../hp/procurve/snmp/mode/virtualchassis.pm | 18 +++---- src/network/huawei/snmp/mode/interfaces.pm | 4 +- src/network/infoblox/snmp/mode/system.pm | 4 +- .../juniper/common/junos/mode/interfaces.pm | 4 +- .../juniper/common/junos/mode/ipsectunnel.pm | 6 +-- .../common/junos/mode/ldpsessionstatus.pm | 4 +- .../juniper/common/junos/mode/lspstatus.pm | 4 +- .../common/junos/mode/rsvpsessionstatus.pm | 4 +- .../juniper/common/junos/mode/stack.pm | 12 ++--- .../juniper/common/screenos/snmp/mode/nsrp.pm | 6 +-- .../common/screenos/snmp/mode/vpnstatus.pm | 4 +- .../juniper/trapeze/snmp/mode/apstatus.pm | 4 +- src/network/kemp/snmp/mode/hastatus.pm | 8 ++-- src/network/kemp/snmp/mode/rsstatus.pm | 4 +- src/network/kemp/snmp/mode/vsstatus.pm | 4 +- .../keysight/nvos/restapi/mode/hardware.pm | 12 ++--- .../keysight/nvos/restapi/mode/ports.pm | 12 ++--- .../keysight/nvos/restapi/mode/time.pm | 2 +- .../lenovo/rackswitch/snmp/mode/hardware.pm | 6 +-- .../lenovo/rackswitch/snmp/mode/interfaces.pm | 4 +- src/network/libraesva/snmp/mode/interfaces.pm | 4 +- src/network/libraesva/snmp/mode/system.pm | 6 +-- .../microsens/g6/snmp/mode/interfaces.pm | 4 +- src/network/microsens/g6/snmp/mode/sfp.pm | 4 +- src/network/mikrotik/snmp/mode/firmware.pm | 4 +- src/network/mikrotik/snmp/mode/interfaces.pm | 4 +- .../mrv/optiswitch/snmp/mode/interfaces.pm | 4 +- .../netgear/sseries/snmp/mode/interfaces.pm | 4 +- src/network/nokia/timos/snmp/mode/bgpusage.pm | 4 +- .../nokia/timos/snmp/mode/isisusage.pm | 4 +- .../nokia/timos/snmp/mode/l2tpusage.pm | 4 +- src/network/nokia/timos/snmp/mode/ldpusage.pm | 4 +- src/network/nokia/timos/snmp/mode/sapusage.pm | 4 +- .../nortel/standard/snmp/mode/interfaces.pm | 4 +- .../nortel/standard/snmp/mode/stack.pm | 6 +-- src/network/oneaccess/snmp/mode/cellsradio.pm | 6 +-- src/network/oneaccess/snmp/mode/interfaces.pm | 4 +- src/network/oneaccess/snmp/mode/rttprobes.pm | 6 +-- src/network/opengear/snmp/mode/interfaces.pm | 4 +- .../infiniband/snmp/mode/infinibandusage.pm | 4 +- src/network/paloalto/snmp/mode/panorama.pm | 4 +- src/network/paloalto/ssh/mode/interfaces.pm | 6 +-- src/network/paloalto/ssh/mode/ipsec.pm | 6 +-- src/network/paloalto/ssh/mode/system.pm | 4 +- .../peplink/pepwave/snmp/mode/wanusage.pm | 4 +- src/network/perle/ids/snmp/mode/alarms.pm | 4 +- src/network/rad/airmux/snmp/mode/alarms.pm | 4 +- .../radware/alteon/snmp/mode/vserverstatus.pm | 4 +- src/network/raisecom/snmp/mode/interfaces.pm | 4 +- src/network/ruckus/scg/snmp/mode/apstatus.pm | 4 +- .../smartzone/snmp/mode/accesspoints.pm | 6 +-- .../zonedirector/snmp/mode/accesspoints.pm | 6 +-- .../ruckus/zonedirector/snmp/mode/system.pm | 6 +-- src/network/silverpeak/snmp/mode/alarms.pm | 4 +- src/network/sonus/sbc/snmp/mode/channels.pm | 4 +- src/network/sonus/sbc/snmp/mode/dspstats.pm | 4 +- src/network/sonus/sbc/snmp/mode/interfaces.pm | 4 +- .../stonesoft/snmp/mode/clusterstate.pm | 6 +-- src/network/stormshield/api/mode/ha.pm | 18 +++---- src/network/stormshield/api/mode/health.pm | 6 +-- .../stormshield/api/mode/interfaces.pm | 6 +-- src/network/stormshield/snmp/mode/hanodes.pm | 4 +- src/network/stormshield/snmp/mode/health.pm | 6 +-- .../stormshield/snmp/mode/vpnstatus.pm | 6 +-- src/network/teltonika/snmp/mode/system.pm | 4 +- .../ubiquiti/airfiber/snmp/mode/radios.pm | 6 +-- .../unifi/snmp/mode/virtualaccesspoints.pm | 6 +-- src/network/ucopia/wlc/snmp/mode/system.pm | 8 ++-- src/network/vectra/restapi/mode/disk.pm | 6 +-- src/network/vectra/restapi/mode/interfaces.pm | 6 +-- src/network/vectra/restapi/mode/memory.pm | 6 +-- src/network/vectra/restapi/mode/sensors.pm | 24 +++++----- .../versa/director/restapi/mode/devices.pm | 6 +-- src/network/versa/snmp/mode/bgppeers.pm | 6 +-- .../viptela/snmp/mode/controlconnections.pm | 6 +-- src/network/viptela/snmp/mode/gretunnels.pm | 6 +-- src/network/viptela/snmp/mode/interfaces.pm | 4 +- src/network/watchguard/snmp/mode/cluster.pm | 12 ++--- src/network/zyxel/snmp/mode/vpnstatus.pm | 4 +- src/os/aix/local/mode/lvsync.pm | 6 +-- src/os/aix/local/mode/process.pm | 4 +- src/os/as400/connector/mode/command.pm | 6 +-- src/os/as400/connector/mode/disks.pm | 6 +-- src/os/as400/connector/mode/jobqueues.pm | 6 +-- src/os/as400/connector/mode/subsystems.pm | 6 +-- src/os/linux/local/mode/checkplugin.pm | 6 +-- src/os/linux/local/mode/discoverysnmp.pm | 4 +- src/os/linux/local/mode/discoverysnmpv3.pm | 2 +- src/os/linux/local/mode/ntp.pm | 6 +-- src/os/linux/local/mode/systemdscstatus.pm | 4 +- src/os/linux/local/mode/traffic.pm | 6 +-- src/os/picos/snmp/mode/interfaces.pm | 4 +- src/os/windows/local/mode/pendingreboot.pm | 4 +- src/os/windows/wsman/mode/pendingreboot.pm | 4 +- src/snmp_standard/mode/interfaces.pm | 4 +- src/snmp_standard/mode/printererror.pm | 8 ++-- src/snmp_standard/mode/spanningtree.pm | 4 +- src/snmp_standard/mode/stringvalue.pm | 7 +-- src/snmp_standard/mode/vrrp.pm | 4 +- .../dell/compellent/snmp/mode/globalstatus.pm | 6 +-- .../dell/equallogic/snmp/mode/diskusage.pm | 6 +-- .../dell/me4/restapi/mode/interfaces.pm | 6 +-- .../dell/powerstore/restapi/mode/alerts.pm | 4 +- .../emc/DataDomain/mode/replication.pm | 6 +-- .../emc/isilon/snmp/mode/clusterusage.pm | 4 +- .../emc/unisphere/restapi/mode/pools.pm | 6 +-- .../unisphere/restapi/mode/replications.pm | 12 ++--- .../restapi/mode/storageresources.pm | 6 +-- .../restapi/mode/clustercommunication.pm | 4 +- .../emc/vplex/restapi/mode/clusterdevices.pm | 4 +- .../emc/vplex/restapi/mode/directors.pm | 20 ++++---- .../vplex/restapi/mode/distributeddevices.pm | 12 ++--- src/storage/emc/vplex/restapi/mode/fans.pm | 8 ++-- src/storage/emc/vplex/restapi/mode/psus.pm | 8 ++-- .../emc/vplex/restapi/mode/storagevolumes.pm | 4 +- .../emc/xtremio/restapi/custom/xtremioapi.pm | 2 +- src/storage/emc/xtremio/restapi/mode/dpg.pm | 6 +-- .../restapi/mode/storagecontrollers.pm | 6 +-- src/storage/exagrid/snmp/mode/serverusage.pm | 4 +- src/storage/hitachi/hcp/snmp/mode/nodes.pm | 24 +++++----- src/storage/hitachi/hcp/snmp/mode/volumes.pm | 6 +-- src/storage/hp/3par/ssh/mode/afc.pm | 2 +- src/storage/hp/3par/ssh/mode/cages.pm | 14 +++--- src/storage/hp/3par/ssh/mode/diskusage.pm | 4 +- src/storage/hp/3par/ssh/mode/nodes.pm | 6 +-- src/storage/hp/3par/ssh/mode/psu.pm | 30 ++++++------ .../hp/lefthand/snmp/mode/volumeusage.pm | 4 +- .../hp/p2000/xmlapi/mode/controllers.pm | 30 ++++++------ src/storage/hp/p2000/xmlapi/mode/vdisks.pm | 6 +-- .../storeonce/3/restapi/mode/clusterusage.pm | 4 +- .../hp/storeonce/3/restapi/mode/fcsusage.pm | 4 +- .../hp/storeonce/3/restapi/mode/nasusage.pm | 8 ++-- .../3/restapi/mode/servicesetusage.pm | 4 +- .../hp/storeonce/4/restapi/mode/appliances.pm | 6 +-- .../hp/storeonce/4/restapi/mode/stores.pm | 6 +-- .../huawei/oceanstor/snmp/mode/controllers.pm | 6 +-- .../oceanstor/snmp/mode/storagepools.pm | 6 +-- .../ibm/storwize/ssh/mode/poolusage.pm | 4 +- .../lenovo/iomega/snmp/mode/interfaces.pm | 4 +- .../oncommandapi/mode/aggregateraidstatus.pm | 4 +- .../oncommandapi/mode/aggregatestatus.pm | 4 +- .../ontap/oncommandapi/mode/clusterstatus.pm | 4 +- .../ontap/oncommandapi/mode/fcportstatus.pm | 4 +- .../oncommandapi/mode/nodefailoverstatus.pm | 4 +- .../oncommandapi/mode/nodehardwarestatus.pm | 4 +- .../ontap/oncommandapi/mode/qtreestatus.pm | 4 +- .../oncommandapi/mode/snapmirrorstatus.pm | 4 +- .../netapp/ontap/oncommandapi/mode/volumes.pm | 6 +-- .../netapp/ontap/restapi/mode/aggregates.pm | 6 +-- .../netapp/ontap/restapi/mode/cluster.pm | 6 +-- src/storage/netapp/ontap/restapi/mode/luns.pm | 6 +-- .../netapp/ontap/restapi/mode/snapmirrors.pm | 6 +-- .../netapp/ontap/restapi/mode/volumes.pm | 6 +-- .../netapp/ontap/snmp/mode/aggregates.pm | 12 ++--- .../netapp/ontap/snmp/mode/clusternodes.pm | 24 +++++----- .../netapp/ontap/snmp/mode/failover.pm | 12 ++--- src/storage/netapp/ontap/snmp/mode/filesys.pm | 6 +-- src/storage/netapp/ontap/snmp/mode/plexes.pm | 6 +-- src/storage/netapp/ontap/snmp/mode/sis.pm | 6 +-- .../netapp/ontap/snmp/mode/snapmirrorlag.pm | 6 +-- .../netapp/ontap/snmp/mode/snapvaultusage.pm | 6 +-- .../netapp/ontap/snmp/mode/volumeoptions.pm | 12 ++--- .../restapi/mode/storagecontrollers.pm | 6 +-- .../santricity/restapi/mode/storagepools.pm | 6 +-- .../santricity/restapi/mode/storagesystems.pm | 6 +-- .../santricity/restapi/mode/storagevolumes.pm | 6 +-- src/storage/nimble/restapi/mode/arrays.pm | 6 +-- src/storage/nimble/restapi/mode/volumes.pm | 6 +-- src/storage/oracle/zs/restapi/mode/pools.pm | 6 +-- .../flasharray/legacy/restapi/mode/alarms.pm | 4 +- .../flasharray/v2/restapi/mode/alerts.pm | 4 +- .../flashblade/v2/restapi/mode/alerts.pm | 4 +- src/storage/qnap/snmp/mode/pools.pm | 6 +-- src/storage/qnap/snmp/mode/upgrade.pm | 4 +- src/storage/qnap/snmp/mode/volumes.pm | 6 +-- .../quantum/dxi/ssh/mode/compaction.pm | 4 +- src/storage/quantum/dxi/ssh/mode/dedupnas.pm | 4 +- src/storage/quantum/dxi/ssh/mode/dedupvtl.pm | 4 +- src/storage/quantum/dxi/ssh/mode/health.pm | 4 +- .../dxi/ssh/mode/hostbusadapterstatus.pm | 4 +- src/storage/quantum/dxi/ssh/mode/network.pm | 4 +- .../quantum/dxi/ssh/mode/reclamation.pm | 4 +- .../dxi/ssh/mode/storagearraystatus.pm | 4 +- .../quantum/dxi/ssh/mode/systemstatus.pm | 4 +- src/storage/synology/snmp/mode/ha.pm | 6 +-- src/storage/synology/snmp/mode/upgrade.pm | 4 +- src/storage/wd/nas/snmp/mode/hardware.pm | 4 +- 731 files changed, 2193 insertions(+), 2143 deletions(-) diff --git a/doc/en/user/guide.rst b/doc/en/user/guide.rst index eddea6df9..00d01f3d4 100644 --- a/doc/en/user/guide.rst +++ b/doc/en/user/guide.rst @@ -489,7 +489,7 @@ You can set the memcached server with the option ``--memcached``: What does ``--dyn-mode`` option do ? ------------------------------------ -With the option, you can used a mode with a plugin. It commonly used for database checks. +With the option, you can use a mode with a plugin. It is commonly used for database checks. For example, I have an application which stores some monitoring information on a database. The developer can use another plugin to create the check (no need to do the SQL connections,... It saves time): :: diff --git a/src/apps/antivirus/clamav/local/mode/updatestatus.pm b/src/apps/antivirus/clamav/local/mode/updatestatus.pm index 56e250204..fff4ca340 100644 --- a/src/apps/antivirus/clamav/local/mode/updatestatus.pm +++ b/src/apps/antivirus/clamav/local/mode/updatestatus.pm @@ -248,32 +248,32 @@ Antivirus daily.cvd file (Default: '/var/lib/clamav/daily.cvd'). =item B<--warning-engine-status> Set warning threshold for status (Default: '') -Can used special variables like: %{last_engine_version}, %{current_engine_version} +You can use the following variables: %{last_engine_version}, %{current_engine_version} =item B<--critical-engine-status> Set critical threshold for status (Default: '%{last_engine_version} ne %{current_engine_version}'). -Can used special variables like: %{last_engine_version}, %{current_engine_version} +You can use the following variables: %{last_engine_version}, %{current_engine_version} =item B<--warning-maindb-status> Set warning threshold for status (Default: '') -Can used special variables like: %{last_maindb_version}, %{current_maindb_version}, %{current_maindb_timediff} +You can use the following variables: %{last_maindb_version}, %{current_maindb_version}, %{current_maindb_timediff} =item B<--critical-maindb-status> Set critical threshold for status (Default: '%{last_maindb_version} ne %{current_maindb_version}'). -Can used special variables like: %{last_maindb_version}, %{current_maindb_version}, %{current_maindb_timediff} +You can use the following variables: %{last_maindb_version}, %{current_maindb_version}, %{current_maindb_timediff} =item B<--warning-dailydb-status> Set warning threshold for status (Default: '') -Can used special variables like: %{last_dailydb_version}, %{current_dailydb_version}, %{current_dailydb_timediff} +You can use the following variables: %{last_dailydb_version}, %{current_dailydb_version}, %{current_dailydb_timediff} =item B<--critical-dailydb-status> Set critical threshold for status (Default: '%{last_dailydb_version} ne %{current_dailydb_version} || %{current_dailydb_timediff} > 432000'). -Can used special variables like: %{last_dailydb_version}, %{current_dailydb_version}, %{current_dailydb_timediff} +You can use the following variables: %{last_dailydb_version}, %{current_dailydb_version}, %{current_dailydb_timediff} =back diff --git a/src/apps/automation/ansible/tower/mode/hosts.pm b/src/apps/automation/ansible/tower/mode/hosts.pm index d5d9bd65e..265ac0e6b 100644 --- a/src/apps/automation/ansible/tower/mode/hosts.pm +++ b/src/apps/automation/ansible/tower/mode/hosts.pm @@ -146,17 +146,17 @@ Display failed hosts list in verbose output. =item B<--unknown-job-status> Set unknown threshold for status (Default: '%{last_job_status} =~ /default/'). -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--warning-job-status> Set warning threshold for status. -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--critical-job-status> Set critical threshold for status (Default: '%{last_job_status} =~ /failed/'). -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/automation/ansible/tower/mode/jobtemplates.pm b/src/apps/automation/ansible/tower/mode/jobtemplates.pm index e8cdd85c9..0d82a5103 100644 --- a/src/apps/automation/ansible/tower/mode/jobtemplates.pm +++ b/src/apps/automation/ansible/tower/mode/jobtemplates.pm @@ -216,17 +216,17 @@ Number of seconds between retries (Default : 10). =item B<--unknown-job-status> Set unknown threshold for status (Default: '%{last_job_status} =~ /default/'). -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--warning-job-status> Set warning threshold for status. -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--critical-job-status> Set critical threshold for status (Default: '%{last_job_status} =~ /failed/'). -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/automation/ansible/tower/mode/schedules.pm b/src/apps/automation/ansible/tower/mode/schedules.pm index 39ad4ea86..c57c678f9 100644 --- a/src/apps/automation/ansible/tower/mode/schedules.pm +++ b/src/apps/automation/ansible/tower/mode/schedules.pm @@ -167,17 +167,17 @@ Filter schedule name (Can use regexp). =item B<--unknown-job-status> Set unknown threshold for status (Default: '%{last_job_status} =~ /default/'). -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--warning-job-status> Set warning threshold for status. -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--critical-job-status> Set critical threshold for status (Default: '%{last_job_status} =~ /failed/'). -Can used special variables like: %{last_job_status}, %{display} +You can use the following variables: %{last_job_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/arcserve/udp/mssql/mode/jobstatus.pm b/src/apps/backup/arcserve/udp/mssql/mode/jobstatus.pm index 547d8402f..629bdbe25 100644 --- a/src/apps/backup/arcserve/udp/mssql/mode/jobstatus.pm +++ b/src/apps/backup/arcserve/udp/mssql/mode/jobstatus.pm @@ -231,17 +231,17 @@ Timezone of mssql server (If not set, we use current server execution timezone). =item B<--ok-status> Set ok threshold for status (Default: '%{status} == 1') -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} == 1') -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{status} != 1'). -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--warning-total> diff --git a/src/apps/backup/backupexec/local/mode/alerts.pm b/src/apps/backup/backupexec/local/mode/alerts.pm index 714fb9ee6..329efdb48 100644 --- a/src/apps/backup/backupexec/local/mode/alerts.pm +++ b/src/apps/backup/backupexec/local/mode/alerts.pm @@ -278,12 +278,12 @@ Only get alerts by severity (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning/i') -Can used special variables like: %{name}, %{severity}, %{source}, %{category}, %{timeraised}, %{message} +You can use the following variables: %{name}, %{severity}, %{source}, %{category}, %{timeraised}, %{message} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /error/i'). -Can used special variables like: %{name}, %{severity}, %{source}, %{category}, %{timeraised}, %{message} +You can use the following variables: %{name}, %{severity}, %{source}, %{category}, %{timeraised}, %{message} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/backupexec/local/mode/disks.pm b/src/apps/backup/backupexec/local/mode/disks.pm index 947e4b70f..c32524720 100644 --- a/src/apps/backup/backupexec/local/mode/disks.pm +++ b/src/apps/backup/backupexec/local/mode/disks.pm @@ -305,12 +305,12 @@ Filter disks by type (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{type}. +You can use the following variables: %{status}, %{name}, %{type}. =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{name}, %{type}. +You can use the following variables: %{status}, %{name}, %{type}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/backupexec/local/mode/jobs.pm b/src/apps/backup/backupexec/local/mode/jobs.pm index 5d5b2d8ae..3a1c8804b 100644 --- a/src/apps/backup/backupexec/local/mode/jobs.pm +++ b/src/apps/backup/backupexec/local/mode/jobs.pm @@ -308,22 +308,22 @@ Filter job with end time greater than current time less value in seconds (Defaul =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}. +You can use the following variables: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}. =item B<--critical-status> Set critical threshold for status (Default: 'not %{status} =~ /succeeded/i'). -Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}. +You can use the following variables: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}. =item B<--warning-long> Set warning threshold for long jobs. -Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}, %{elapsed}. +You can use the following variables: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}, %{elapsed}. =item B<--critical-long> Set critical threshold for long jobs. -Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}, %{elapsed}. +You can use the following variables: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}, %{elapsed}. =item B<--warning-detected> diff --git a/src/apps/backup/commvault/commserve/restapi/mode/alerts.pm b/src/apps/backup/commvault/commserve/restapi/mode/alerts.pm index 64c39c6eb..6b4ac6166 100644 --- a/src/apps/backup/commvault/commserve/restapi/mode/alerts.pm +++ b/src/apps/backup/commvault/commserve/restapi/mode/alerts.pm @@ -212,12 +212,12 @@ Filter alerts by type (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning/') -Can used special variables like: %{severity}, %{status}, %{type}, %{name}, %{since} +You can use the following variables: %{severity}, %{status}, %{type}, %{name}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical/'). -Can used special variables like: %{severity}, %{status}, %{type}, %{name}, %{since} +You can use the following variables: %{severity}, %{status}, %{type}, %{name}, %{since} =item B<--memory> diff --git a/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm b/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm index 2b1b7cfde..f343dc15b 100644 --- a/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm +++ b/src/apps/backup/commvault/commserve/restapi/mode/jobs.pm @@ -266,22 +266,22 @@ Set timeframe in seconds (E.g '3600' to check last 60 minutes). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /abnormal/i') -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /errors|failed/i'). -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--warning-long> Set warning threshold for long jobs. -Can used special variables like: %{display}, %{status}, %{elapsed}, %{type} +You can use the following variables: %{display}, %{status}, %{elapsed}, %{type} =item B<--critical-long> Set critical threshold for long jobs. -Can used special variables like: %{display}, %{status}, %{elapsed}, %{type} +You can use the following variables: %{display}, %{status}, %{elapsed}, %{type} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/commvault/commserve/restapi/mode/mediaagents.pm b/src/apps/backup/commvault/commserve/restapi/mode/mediaagents.pm index f3c373186..2ef21ad6c 100644 --- a/src/apps/backup/commvault/commserve/restapi/mode/mediaagents.pm +++ b/src/apps/backup/commvault/commserve/restapi/mode/mediaagents.pm @@ -178,17 +178,17 @@ Filter media agents by name (Can be a regexp). =item B<--unknown-device-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{is_maintenance}, %{offline_reason}, %{name} +You can use the following variables: %{status}, %{is_maintenance}, %{offline_reason}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{is_maintenance} eq "no" and %{status} eq "offline"'). -Can used special variables like: %{status}, %{is_maintenance}, %{offline_reason}, %{name} +You can use the following variables: %{status}, %{is_maintenance}, %{offline_reason}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm b/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm index 383d054b6..0705458aa 100644 --- a/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm +++ b/src/apps/backup/commvault/commserve/restapi/mode/storagepools.pm @@ -167,17 +167,17 @@ Filter storage pools by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /online/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/netapp/snapcenter/restapi/mode/jobs.pm b/src/apps/backup/netapp/snapcenter/restapi/mode/jobs.pm index 21c47fe11..f7d072bfb 100644 --- a/src/apps/backup/netapp/snapcenter/restapi/mode/jobs.pm +++ b/src/apps/backup/netapp/snapcenter/restapi/mode/jobs.pm @@ -252,17 +252,17 @@ Set timezone (If not set, we use current server execution timezone). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--warning-total> diff --git a/src/apps/backup/netbackup/local/mode/dedupstatus.pm b/src/apps/backup/netbackup/local/mode/dedupstatus.pm index f6c590180..1dab88953 100644 --- a/src/apps/backup/netbackup/local/mode/dedupstatus.pm +++ b/src/apps/backup/netbackup/local/mode/dedupstatus.pm @@ -207,12 +207,12 @@ Set critical threshold in percent. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /up/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =back diff --git a/src/apps/backup/netbackup/local/mode/drivestatus.pm b/src/apps/backup/netbackup/local/mode/drivestatus.pm index 840e54484..097c47b95 100644 --- a/src/apps/backup/netbackup/local/mode/drivestatus.pm +++ b/src/apps/backup/netbackup/local/mode/drivestatus.pm @@ -133,12 +133,12 @@ Filter drive name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /up/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =back diff --git a/src/apps/backup/netbackup/local/mode/jobstatus.pm b/src/apps/backup/netbackup/local/mode/jobstatus.pm index 8302f704c..40575db83 100644 --- a/src/apps/backup/netbackup/local/mode/jobstatus.pm +++ b/src/apps/backup/netbackup/local/mode/jobstatus.pm @@ -336,38 +336,38 @@ Filter job with end time greater than current time less value in seconds (Defaul =item B<--ok-status> Set ok threshold for status (Default: '%{status} == 0') -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} == 1') -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{status} > 1'). -Can used special variables like: %{display}, %{status}, %{type} +You can use the following variables: %{display}, %{status}, %{type} =item B<--warning-long> Set warning threshold for long jobs (Default: none) -Can used special variables like: %{display}, %{status}, %{elapsed}, %{type} +You can use the following variables: %{display}, %{status}, %{elapsed}, %{type} =item B<--critical-long> Set critical threshold for long jobs (Default: none). -Can used special variables like: %{display}, %{status}, %{elapsed}, %{type} +You can use the following variables: %{display}, %{status}, %{elapsed}, %{type} =item B<--warning-frozen> Set warning threshold for frozen jobs (Default: none) -Can used special variables like: +You can use the following variables: %{display}, %{status}, %{elapsed}, %{type}, %{kb}, %{parentid}, %{schedule}, %{jobid} =item B<--critical-frozen> Set critical threshold for frozen jobs (Default: '%{state} =~ /active|queue/ && %{kb} == 0'). -Can used special variables like: +You can use the following variables: %{display}, %{status}, %{elapsed}, %{type}, %{kb}, %{parentid}, %{schedule}, %{jobid} =item B<--warning-total> diff --git a/src/apps/backup/quadstor/local/mode/vtldiskusage.pm b/src/apps/backup/quadstor/local/mode/vtldiskusage.pm index f3519b174..955f14c0c 100644 --- a/src/apps/backup/quadstor/local/mode/vtldiskusage.pm +++ b/src/apps/backup/quadstor/local/mode/vtldiskusage.pm @@ -226,12 +226,12 @@ Thresholds are on free tape left. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /active/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/apps/backup/quadstor/local/mode/vtljobstatus.pm b/src/apps/backup/quadstor/local/mode/vtljobstatus.pm index 8be950d8b..ec34cca57 100644 --- a/src/apps/backup/quadstor/local/mode/vtljobstatus.pm +++ b/src/apps/backup/quadstor/local/mode/vtljobstatus.pm @@ -177,32 +177,32 @@ Command used: '/quadstorvtl/bin/impexp -l' =item B<--warning-status> Set warning threshold for status (Default: none) -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--warning-long> Set warning threshold for long jobs (Default: none) -Can used special variables like: %{display}, %{status}, %{elapsed} +You can use the following variables: %{display}, %{status}, %{elapsed} =item B<--critical-long> Set critical threshold for long jobs (Default: none). -Can used special variables like: %{display}, %{status}, %{elapsed} +You can use the following variables: %{display}, %{status}, %{elapsed} =item B<--warning-frozen> Set warning threshold for frozen jobs (Default: none) -Can used special variables like: %{display}, %{status}, %{elapsed}, %{kb} +You can use the following variables: %{display}, %{status}, %{elapsed}, %{kb} =item B<--critical-frozen> Set critical threshold for frozen jobs (Default: none). -Can used special variables like: %{display}, %{status}, %{elapsed}, %{kb} +You can use the following variables: %{display}, %{status}, %{elapsed}, %{kb} =back diff --git a/src/apps/backup/quadstor/local/mode/vtltapeusage.pm b/src/apps/backup/quadstor/local/mode/vtltapeusage.pm index 41fa4cf5d..f5aeae453 100644 --- a/src/apps/backup/quadstor/local/mode/vtltapeusage.pm +++ b/src/apps/backup/quadstor/local/mode/vtltapeusage.pm @@ -252,12 +252,12 @@ Thresholds are on free tape left. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /active/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/rapidrecovery/snmp/mode/agent.pm b/src/apps/backup/rapidrecovery/snmp/mode/agent.pm index bdf5f88fd..90525aaa2 100644 --- a/src/apps/backup/rapidrecovery/snmp/mode/agent.pm +++ b/src/apps/backup/rapidrecovery/snmp/mode/agent.pm @@ -158,17 +158,17 @@ Check agents. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unreachable/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /failed|authenticationError/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/rapidrecovery/snmp/mode/repository.pm b/src/apps/backup/rapidrecovery/snmp/mode/repository.pm index f006046ee..dffb5be76 100644 --- a/src/apps/backup/rapidrecovery/snmp/mode/repository.pm +++ b/src/apps/backup/rapidrecovery/snmp/mode/repository.pm @@ -188,17 +188,17 @@ Check repositories. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/rubrik/restapi/mode/cluster.pm b/src/apps/backup/rubrik/restapi/mode/cluster.pm index e55dbcfe6..915b0f6a7 100644 --- a/src/apps/backup/rubrik/restapi/mode/cluster.pm +++ b/src/apps/backup/rubrik/restapi/mode/cluster.pm @@ -174,17 +174,17 @@ Which cluster to check (Default: 'me'). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/rubrik/restapi/mode/disks.pm b/src/apps/backup/rubrik/restapi/mode/disks.pm index c19112e25..ebbaf6eb8 100644 --- a/src/apps/backup/rubrik/restapi/mode/disks.pm +++ b/src/apps/backup/rubrik/restapi/mode/disks.pm @@ -178,17 +178,17 @@ Filter disks by disk id (can be a regexp). =item B<--unknown-disks-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{id} +You can use the following variables: %{status}, %{id} =item B<--warning-disk-status> Set warning threshold for status. -Can used special variables like: %{status}, %{id} +You can use the following variables: %{status}, %{id} =item B<--critical-disk-status> Set critical threshold for status (Default: '%{status} !~ /active/i'). -Can used special variables like: %{status}, %{id} +You can use the following variables: %{status}, %{id} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/rubrik/restapi/mode/nodes.pm b/src/apps/backup/rubrik/restapi/mode/nodes.pm index cbbb446f0..0f82513de 100644 --- a/src/apps/backup/rubrik/restapi/mode/nodes.pm +++ b/src/apps/backup/rubrik/restapi/mode/nodes.pm @@ -178,17 +178,17 @@ Filter nodes by node id (can be a regexp). =item B<--unknown-node-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{ip_address}, %{id} +You can use the following variables: %{status}, %{ip_address}, %{id} =item B<--warning-node-status> Set warning threshold for status. -Can used special variables like: %{status}, %{ip_address}, %{id} +You can use the following variables: %{status}, %{ip_address}, %{id} =item B<--critical-node-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{ip_address}, %{id} +You can use the following variables: %{status}, %{ip_address}, %{id} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/tsm/local/mode/actlog.pm b/src/apps/backup/tsm/local/mode/actlog.pm index 2cd24936c..21ee83654 100644 --- a/src/apps/backup/tsm/local/mode/actlog.pm +++ b/src/apps/backup/tsm/local/mode/actlog.pm @@ -159,12 +159,12 @@ Get activity log more recent than X hour(s) (default: '1'). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning/') -Can used special variables like: %{message}, %{severity}, %{since} +You can use the following variables: %{message}, %{severity}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /error|severe/'). -Can used special variables like: %{message}, %{severity}, %{since} +You can use the following variables: %{message}, %{severity}, %{since} =item B<--timezone> diff --git a/src/apps/backup/tsm/local/mode/sessions.pm b/src/apps/backup/tsm/local/mode/sessions.pm index 89bdc49d5..0e13aa9b8 100644 --- a/src/apps/backup/tsm/local/mode/sessions.pm +++ b/src/apps/backup/tsm/local/mode/sessions.pm @@ -182,12 +182,12 @@ Filter by session type. =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{client_name}, %{state}, %{session_type}, %{since} +You can use the following variables: %{client_name}, %{state}, %{session_type}, %{since} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{client_name}, %{state}, %{session_type}, %{since} +You can use the following variables: %{client_name}, %{state}, %{session_type}, %{since} =item B<--warning-*> diff --git a/src/apps/backup/veeam/local/mode/jobstatus.pm b/src/apps/backup/veeam/local/mode/jobstatus.pm index d106d3ad5..f84953bea 100644 --- a/src/apps/backup/veeam/local/mode/jobstatus.pm +++ b/src/apps/backup/veeam/local/mode/jobstatus.pm @@ -319,27 +319,27 @@ Filter job with end time greater than current time less value in seconds (Defaul =item B<--ok-status> Set ok threshold for status. -Can used special variables like: %{display}, %{status}, %{type}, %{is_running}, %{scheduled}. +You can use the following variables: %{display}, %{status}, %{type}, %{is_running}, %{scheduled}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{status}, %{type}, %{is_running}, %{scheduled}. +You can use the following variables: %{display}, %{status}, %{type}, %{is_running}, %{scheduled}. =item B<--critical-status> Set critical threshold for status (Default: '%{is_running} == 0 and not %{status} =~ /Success/i'). -Can used special variables like: %{display}, %{status}, %{type}, %{is_running}, %{scheduled}. +You can use the following variables: %{display}, %{status}, %{type}, %{is_running}, %{scheduled}. =item B<--warning-long> Set warning threshold for long jobs. -Can used special variables like: %{display}, %{status}, %{type}, %{elapsed}. +You can use the following variables: %{display}, %{status}, %{type}, %{elapsed}. =item B<--critical-long> Set critical threshold for long jobs. -Can used special variables like: %{display}, %{status}, %{type}, %{elapsed}. +You can use the following variables: %{display}, %{status}, %{type}, %{elapsed}. =item B<--warning-total> diff --git a/src/apps/backup/veeam/local/mode/licenses.pm b/src/apps/backup/veeam/local/mode/licenses.pm index 02b273799..1f4acdaa3 100644 --- a/src/apps/backup/veeam/local/mode/licenses.pm +++ b/src/apps/backup/veeam/local/mode/licenses.pm @@ -338,12 +338,12 @@ Filter licenses by status (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{to}, %{status}, %{type}. +You can use the following variables: %{to}, %{status}, %{type}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /expired|invalid/i'). -Can used special variables like: %{to}, %{status}, %{type}. +You can use the following variables: %{to}, %{status}, %{type}. =item B<--unit> diff --git a/src/apps/backup/veeam/local/mode/repositories.pm b/src/apps/backup/veeam/local/mode/repositories.pm index 5e98b57f2..de9ac9a73 100644 --- a/src/apps/backup/veeam/local/mode/repositories.pm +++ b/src/apps/backup/veeam/local/mode/repositories.pm @@ -302,12 +302,12 @@ Filter repositories by type (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{type}. +You can use the following variables: %{status}, %{name}, %{type}. =item B<--critical-status> Set critical threshold for status (Default: 'not %{status} =~ /ordinal|maintenance/i'). -Can used special variables like: %{status}, %{name}, %{type}. +You can use the following variables: %{status}, %{name}, %{type}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/backup/veeam/local/mode/tapejobs.pm b/src/apps/backup/veeam/local/mode/tapejobs.pm index e443f844d..b75663413 100644 --- a/src/apps/backup/veeam/local/mode/tapejobs.pm +++ b/src/apps/backup/veeam/local/mode/tapejobs.pm @@ -255,17 +255,17 @@ Filter job type (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '') -Can used special variables like: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. +You can use the following variables: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. +You can use the following variables: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. =item B<--critical-status> Set critical threshold for status (Default: '%{enabled} == 1 and not %{last_result} =~ /Success|None/i'). -Can used special variables like: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. +You can use the following variables: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. =item B<--warning-total> diff --git a/src/apps/backup/veeam/local/mode/vsbjobs.pm b/src/apps/backup/veeam/local/mode/vsbjobs.pm index 48949d4e6..8c699725b 100644 --- a/src/apps/backup/veeam/local/mode/vsbjobs.pm +++ b/src/apps/backup/veeam/local/mode/vsbjobs.pm @@ -291,17 +291,17 @@ Filter job type (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{name}, %{type}, %{status}, %{duration}. +You can use the following variables: %{name}, %{type}, %{status}, %{duration}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{type}, %{status}, %{duration}. +You can use the following variables: %{name}, %{type}, %{status}, %{duration}. =item B<--critical-status> Set critical threshold for status (Default: 'not %{status} =~ /success/i'). -Can used special variables like: %{name}, %{type}, %{status}, %{duration}. +You can use the following variables: %{name}, %{type}, %{status}, %{duration}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/centreon/local/mode/brokerstats.pm b/src/apps/centreon/local/mode/brokerstats.pm index 091daf519..17d65ebb4 100644 --- a/src/apps/centreon/local/mode/brokerstats.pm +++ b/src/apps/centreon/local/mode/brokerstats.pm @@ -245,12 +245,12 @@ Can be: 'speed-events', 'queued-events', 'unacknowledged-events'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{queue_file_enabled}, %{state}, %{status}, %{type}, %{display} +You can use the following variables: %{queue_file_enabled}, %{state}, %{status}, %{type}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{type} eq "output" and %{queue_file_enabled} =~ /yes/i'). -Can used special variables like: %{queue_file_enabled}, %{state}, %{status}, %{type}, %{display} +You can use the following variables: %{queue_file_enabled}, %{state}, %{status}, %{type}, %{display} =back diff --git a/src/apps/ceph/restapi/mode/health.pm b/src/apps/ceph/restapi/mode/health.pm index 0fc0e5dd6..8ceefde9c 100644 --- a/src/apps/ceph/restapi/mode/health.pm +++ b/src/apps/ceph/restapi/mode/health.pm @@ -101,12 +101,12 @@ Check overall cluster status. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /warn/i') -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error/i'). -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =back diff --git a/src/apps/cisco/cms/restapi/mode/alarms.pm b/src/apps/cisco/cms/restapi/mode/alarms.pm index e2f7e6655..9e6cc8ead 100644 --- a/src/apps/cisco/cms/restapi/mode/alarms.pm +++ b/src/apps/cisco/cms/restapi/mode/alarms.pm @@ -145,12 +145,12 @@ Filter by type (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{type}, %{active_time} +You can use the following variables: %{type}, %{active_time} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{type}, %{active_time} +You can use the following variables: %{type}, %{active_time} =item B<--memory> diff --git a/src/apps/cisco/ssms/restapi/mode/licenses.pm b/src/apps/cisco/ssms/restapi/mode/licenses.pm index c4a8dd43e..751f7d592 100644 --- a/src/apps/cisco/ssms/restapi/mode/licenses.pm +++ b/src/apps/cisco/ssms/restapi/mode/licenses.pm @@ -199,17 +199,17 @@ Filter license name (can be a regexp). =item B<--unknown-license-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-license-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-license-status> Set critical threshold for status (Default: '%{status} !~ /in compliance/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/controlm/restapi/mode/jobs.pm b/src/apps/controlm/restapi/mode/jobs.pm index 20ca5072d..0953d7b7d 100644 --- a/src/apps/controlm/restapi/mode/jobs.pm +++ b/src/apps/controlm/restapi/mode/jobs.pm @@ -304,22 +304,22 @@ Can use format: 'Europe/London' or '+0100'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{status}, %{application}, %{folder}, %{type} +You can use the following variables: %{name}, %{status}, %{application}, %{folder}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /ended not ok/i'). -Can used special variables like: %{name}, %{status}, %{application}, %{folder}, %{type} +You can use the following variables: %{name}, %{status}, %{application}, %{folder}, %{type} =item B<--warning-long> Set warning threshold for long jobs. -Can used special variables like: %{name}, %{status}, %{elapsed}, %{application}, %{folder}, %{type} +You can use the following variables: %{name}, %{status}, %{elapsed}, %{application}, %{folder}, %{type} =item B<--critical-long> Set critical threshold for long jobs. -Can used special variables like: %{name}, %{status}, %{elapsed}, %{application}, %{folder}, %{type} +You can use the following variables: %{name}, %{status}, %{elapsed}, %{application}, %{folder}, %{type} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/emc/ppma/restapi/mode/hosts.pm b/src/apps/emc/ppma/restapi/mode/hosts.pm index d66f25257..c4eb225e1 100644 --- a/src/apps/emc/ppma/restapi/mode/hosts.pm +++ b/src/apps/emc/ppma/restapi/mode/hosts.pm @@ -199,17 +199,17 @@ Filter hosts by host name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /powerPathManaged/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/ericsson/enm/api/mode/nodes.pm b/src/apps/ericsson/enm/api/mode/nodes.pm index 90e0a0266..46ce7a6a1 100644 --- a/src/apps/ericsson/enm/api/mode/nodes.pm +++ b/src/apps/ericsson/enm/api/mode/nodes.pm @@ -261,47 +261,47 @@ Filter tdd cells by id (can be a regexp). =item B<--unknown-node-sync-status> Set unknown threshold for synchronization status. -Can used special variables like: %{node_id}, %{sync_status} +You can use the following variables: %{node_id}, %{sync_status} =item B<--warning-node-sync-status> Set warning threshold for synchronization status. -Can used special variables like: %{node_id}, %{sync_status} +You can use the following variables: %{node_id}, %{sync_status} =item B<--critical-node-sync-status> Set critical threshold for synchronization status (Default: '%{sync_status} =~ /unsynchronized/i'). -Can used special variables like: %{node_id}, %{sync_status} +You can use the following variables: %{node_id}, %{sync_status} =item B<--unknown-fru-status> Set unknown threshold for field replaceable unit status. -Can used special variables like: %{node_id}, %{fru_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} +You can use the following variables: %{node_id}, %{fru_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} =item B<--warning-fru-status> Set warning threshold for field replaceable unit status. -Can used special variables like: %{node_id}, %{fru_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} +You can use the following variables: %{node_id}, %{fru_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} =item B<--critical-fru-status> Set critical threshold for field replaceable unit status. -Can used special variables like: %{node_id}, %{fru_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} +You can use the following variables: %{node_id}, %{fru_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} =item B<--unknown-cell-tdd-status> Set unknown threshold for cell tdd status. -Can used special variables like: %{node_id}, %{cell_tdd_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} +You can use the following variables: %{node_id}, %{cell_tdd_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} =item B<--warning-cell-tdd-status> Set warning threshold for cell tdd status. -Can used special variables like: %{node_id}, %{cell_tdd_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} +You can use the following variables: %{node_id}, %{cell_tdd_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} =item B<--critical-cell-tdd-status> Set critical threshold for cell tdd status. -Can used special variables like: %{node_id}, %{cell_tdd_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} +You can use the following variables: %{node_id}, %{cell_tdd_id}, %{label}, %{administrative_state}, %{availability_status}, %{operational_state} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/grafana/api/mode/health.pm b/src/apps/grafana/api/mode/health.pm index e6f82173a..4013481ba 100644 --- a/src/apps/grafana/api/mode/health.pm +++ b/src/apps/grafana/api/mode/health.pm @@ -88,12 +88,12 @@ Check health. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{version} +You can use the following variables: %{state}, %{version} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "ok"'). -Can used special variables like: %{state}, %{version} +You can use the following variables: %{state}, %{version} =back diff --git a/src/apps/haproxy/snmp/mode/backendusage.pm b/src/apps/haproxy/snmp/mode/backendusage.pm index 40c53c0c2..7e87a50c5 100644 --- a/src/apps/haproxy/snmp/mode/backendusage.pm +++ b/src/apps/haproxy/snmp/mode/backendusage.pm @@ -235,12 +235,12 @@ Filter backend name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /UP/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/haproxy/snmp/mode/frontendusage.pm b/src/apps/haproxy/snmp/mode/frontendusage.pm index 8fb9119d5..430607b23 100644 --- a/src/apps/haproxy/snmp/mode/frontendusage.pm +++ b/src/apps/haproxy/snmp/mode/frontendusage.pm @@ -226,12 +226,12 @@ Filter backend name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /OPEN/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/hddtemp/mode/temperatures.pm b/src/apps/hddtemp/mode/temperatures.pm index 8e8bbcb94..46bc5dd64 100644 --- a/src/apps/hddtemp/mode/temperatures.pm +++ b/src/apps/hddtemp/mode/temperatures.pm @@ -147,17 +147,17 @@ Filter drive name (Can use regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/ibm/tsamp/local/mode/resourcegroups.pm b/src/apps/ibm/tsamp/local/mode/resourcegroups.pm index 47eba739b..3aaa561f3 100644 --- a/src/apps/ibm/tsamp/local/mode/resourcegroups.pm +++ b/src/apps/ibm/tsamp/local/mode/resourcegroups.pm @@ -171,17 +171,17 @@ Exclude resource groups by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{opState} =~ /unknown/i'). -Can used special variables like: %{opState}, %{nominalState}, %{name} +You can use the following variables: %{opState}, %{nominalState}, %{name} =item B<--warning-status> Set warning threshold for status (Default: '%{opState} =~ /pending/i'). -Can used special variables like: %{opState}, %{nominalState}, %{name} +You can use the following variables: %{opState}, %{nominalState}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{opState} =~ /failed offline|stuck online/i || %{opState} ne %{nominalState}'). -Can used special variables like: %{opState}, %{nominalState}, %{name} +You can use the following variables: %{opState}, %{nominalState}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/inin/ig/snmp/mode/spanusage.pm b/src/apps/inin/ig/snmp/mode/spanusage.pm index b8bba26fa..fff598de8 100644 --- a/src/apps/inin/ig/snmp/mode/spanusage.pm +++ b/src/apps/inin/ig/snmp/mode/spanusage.pm @@ -158,12 +158,12 @@ Filter span name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /closed|ready/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm b/src/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm index 03113d23b..9f6696f7e 100644 --- a/src/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm +++ b/src/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm @@ -242,12 +242,12 @@ Filter client name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{accept_sessions}, %{status}, %{display} +You can use the following variables: %{accept_sessions}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^ready/i'). -Can used special variables like: %{accept_sessions}, %{status}, %{display} +You can use the following variables: %{accept_sessions}, %{status}, %{display} =item B<--warning-*> diff --git a/src/apps/java/awa/jmx/mode/agent.pm b/src/apps/java/awa/jmx/mode/agent.pm index 5c4f8dde8..e236c430b 100644 --- a/src/apps/java/awa/jmx/mode/agent.pm +++ b/src/apps/java/awa/jmx/mode/agent.pm @@ -168,12 +168,12 @@ Filter agent name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{since}, %{display}, %{ipaddress}, %{active} +You can use the following variables: %{since}, %{display}, %{ipaddress}, %{active} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{since}, %{display}, %{ipaddress}, %{active} +You can use the following variables: %{since}, %{display}, %{ipaddress}, %{active} =item B<--timezone> diff --git a/src/apps/java/awa/jmx/mode/queue.pm b/src/apps/java/awa/jmx/mode/queue.pm index 44ff9cfd0..bb1d1b343 100644 --- a/src/apps/java/awa/jmx/mode/queue.pm +++ b/src/apps/java/awa/jmx/mode/queue.pm @@ -139,12 +139,12 @@ Filter queue name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /GREEN/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =back diff --git a/src/apps/java/awa/jmx/mode/server.pm b/src/apps/java/awa/jmx/mode/server.pm index f28d63588..a202f72e6 100644 --- a/src/apps/java/awa/jmx/mode/server.pm +++ b/src/apps/java/awa/jmx/mode/server.pm @@ -143,12 +143,12 @@ Filter server name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{display}, %{ipaddress}, %{active} +You can use the following variables: %{display}, %{ipaddress}, %{active} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{display}, %{ipaddress}, %{active} +You can use the following variables: %{display}, %{ipaddress}, %{active} =back diff --git a/src/apps/keepalived/snmp/mode/vrrpstatus.pm b/src/apps/keepalived/snmp/mode/vrrpstatus.pm index d1e258f25..a820eaf58 100644 --- a/src/apps/keepalived/snmp/mode/vrrpstatus.pm +++ b/src/apps/keepalived/snmp/mode/vrrpstatus.pm @@ -144,12 +144,12 @@ Check VRRP instances status. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{instanceWantedState}, %{instanceStateLast}, %{instanceState}, %{instancePrimaryInterface} +You can use the following variables: %{instanceWantedState}, %{instanceStateLast}, %{instanceState}, %{instancePrimaryInterface} =item B<--critical-status> Set critical threshold for status (Default: '%{instanceState} ne %{instanceWantedState} or %{instanceState} ne %{instanceStateLast}'). -Can used special variables like: %{instanceWantedState}, %{instanceStateLast}, %{instanceState}, %{instancePrimaryInterface} +You can use the following variables: %{instanceWantedState}, %{instanceStateLast}, %{instanceState}, %{instancePrimaryInterface} =back diff --git a/src/apps/microsoft/dhcp/snmp/mode/subnets.pm b/src/apps/microsoft/dhcp/snmp/mode/subnets.pm index 9df1296ab..e99ce1933 100644 --- a/src/apps/microsoft/dhcp/snmp/mode/subnets.pm +++ b/src/apps/microsoft/dhcp/snmp/mode/subnets.pm @@ -202,17 +202,17 @@ Filter subnets by address (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/microsoft/exchange/local/mode/activesyncmailbox.pm b/src/apps/microsoft/exchange/local/mode/activesyncmailbox.pm index 2c5578362..05d1d91c2 100644 --- a/src/apps/microsoft/exchange/local/mode/activesyncmailbox.pm +++ b/src/apps/microsoft/exchange/local/mode/activesyncmailbox.pm @@ -190,12 +190,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--critical> Set critical threshold (Default: '%{result} !~ /Success/i'). -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--mailbox> diff --git a/src/apps/microsoft/exchange/local/mode/databases.pm b/src/apps/microsoft/exchange/local/mode/databases.pm index c3904a690..2c0cd0fbd 100644 --- a/src/apps/microsoft/exchange/local/mode/databases.pm +++ b/src/apps/microsoft/exchange/local/mode/databases.pm @@ -447,42 +447,42 @@ Skip mapi/mailflow test (regexp can be used. In Powershell). =item B<--warning-status> Set warning threshold. -Can used special variables like: %{mounted}, %{database}, %{server} +You can use the following variables: %{mounted}, %{database}, %{server} =item B<--critical-status> Set critical threshold (Default: '%{mounted} == 0'). -Can used special variables like: %{mounted}, %{database}, %{server} +You can use the following variables: %{mounted}, %{database}, %{server} =item B<--warning-mapi> Set warning threshold. -Can used special variables like: %{mapi_result}, %{database}, %{server} +You can use the following variables: %{mapi_result}, %{database}, %{server} =item B<--critical-mapi> Set critical threshold (Default: '%{mapi_result} !~ /Success/i'). -Can used special variables like: %{mapi_result}, %{database}, %{server} +You can use the following variables: %{mapi_result}, %{database}, %{server} =item B<--warning-mailflow> Set warning threshold. -Can used special variables like: %{mailflow_result}, %{database}, %{server} +You can use the following variables: %{mailflow_result}, %{database}, %{server} =item B<--critical-mailflow> Set critical threshold (Default: '%{mailflow_result} !~ /Success/i'). -Can used special variables like: %{mailflow_result}, %{database}, %{server} +You can use the following variables: %{mailflow_result}, %{database}, %{server} =item B<--warning-copystatus> Set warning threshold. -Can used special variables like: %{mailflow_result}, %{database}, %{server} +You can use the following variables: %{mailflow_result}, %{database}, %{server} =item B<--critical-copystatus> Set critical threshold (Default: '%{contentindexstate} !~ /Healthy/i'). -Can used special variables like: %{copystatus_indexstate}, %{database}, %{server} +You can use the following variables: %{copystatus_indexstate}, %{database}, %{server} =back diff --git a/src/apps/microsoft/exchange/local/mode/imapmailbox.pm b/src/apps/microsoft/exchange/local/mode/imapmailbox.pm index 2c0e4f594..636430652 100644 --- a/src/apps/microsoft/exchange/local/mode/imapmailbox.pm +++ b/src/apps/microsoft/exchange/local/mode/imapmailbox.pm @@ -188,12 +188,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--critical> Set critical threshold (Default: '%{result} !~ /Success/i'). -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--mailbox> diff --git a/src/apps/microsoft/exchange/local/mode/mapimailbox.pm b/src/apps/microsoft/exchange/local/mode/mapimailbox.pm index 1561128ad..8b70588dc 100644 --- a/src/apps/microsoft/exchange/local/mode/mapimailbox.pm +++ b/src/apps/microsoft/exchange/local/mode/mapimailbox.pm @@ -182,12 +182,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--critical> Set critical threshold (Default: '%{result} !~ /Success/i'). -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--mailbox> diff --git a/src/apps/microsoft/exchange/local/mode/outlookwebservices.pm b/src/apps/microsoft/exchange/local/mode/outlookwebservices.pm index 98388549b..3431a1c44 100644 --- a/src/apps/microsoft/exchange/local/mode/outlookwebservices.pm +++ b/src/apps/microsoft/exchange/local/mode/outlookwebservices.pm @@ -184,12 +184,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{type}, %{id}, %{message} +You can use the following variables: %{type}, %{id}, %{message} =item B<--critical> Set critical threshold (Default: '%{type} !~ /Success|Information/i'). -Can used special variables like: %{type}, %{id}, %{message} +You can use the following variables: %{type}, %{id}, %{message} =item B<--mailbox> diff --git a/src/apps/microsoft/exchange/local/mode/owamailbox.pm b/src/apps/microsoft/exchange/local/mode/owamailbox.pm index 12a8d43b7..b30d1aeb5 100644 --- a/src/apps/microsoft/exchange/local/mode/owamailbox.pm +++ b/src/apps/microsoft/exchange/local/mode/owamailbox.pm @@ -196,12 +196,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--critical> Set critical threshold (Default: '%{result} !~ /Success/i'). -Can used special variables like: %{result}, %{scenario} +You can use the following variables: %{result}, %{scenario} =item B<--url> diff --git a/src/apps/microsoft/exchange/local/mode/queues.pm b/src/apps/microsoft/exchange/local/mode/queues.pm index 80bc86e90..4aa70955e 100644 --- a/src/apps/microsoft/exchange/local/mode/queues.pm +++ b/src/apps/microsoft/exchange/local/mode/queues.pm @@ -248,12 +248,12 @@ Print powershell output. =item B<--warning-status> Set warning threshold. -Can used special variables like: %{status}, %{identity}, %{is_valid}, %{delivery_type}, %{message_count} +You can use the following variables: %{status}, %{identity}, %{is_valid}, %{delivery_type}, %{message_count} =item B<--critical-status> Set critical threshold (Default: '%{status} !~ /Ready|Active/i'). -Can used special variables like: %{status}, %{identity}, %{is_valid}, %{delivery_type}, %{message_count} +You can use the following variables: %{status}, %{identity}, %{is_valid}, %{delivery_type}, %{message_count} =back diff --git a/src/apps/microsoft/exchange/local/mode/replicationhealth.pm b/src/apps/microsoft/exchange/local/mode/replicationhealth.pm index 7d068de8b..7897e7f5f 100644 --- a/src/apps/microsoft/exchange/local/mode/replicationhealth.pm +++ b/src/apps/microsoft/exchange/local/mode/replicationhealth.pm @@ -175,12 +175,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{result}, %{server}, %{isvalid}, %{check} +You can use the following variables: %{result}, %{server}, %{isvalid}, %{check} =item B<--critical> Set critical threshold (Default: '%{result} !~ /Passed/i'). -Can used special variables like: %{result}, %{server}, %{isvalid}, %{check} +You can use the following variables: %{result}, %{server}, %{isvalid}, %{check} =back diff --git a/src/apps/microsoft/exchange/local/mode/services.pm b/src/apps/microsoft/exchange/local/mode/services.pm index 024a696e4..25be94563 100644 --- a/src/apps/microsoft/exchange/local/mode/services.pm +++ b/src/apps/microsoft/exchange/local/mode/services.pm @@ -175,12 +175,12 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{servicesrunning}, %{servicesnotrunning}, %{role}, %{requiredservicesrunning} +You can use the following variables: %{servicesrunning}, %{servicesnotrunning}, %{role}, %{requiredservicesrunning} =item B<--critical> Set critical threshold (Default: '%{requiredservicesrunning} =~ /True/i and %{servicesnotrunning} ne ""'). -Can used special variables like: %{servicesrunning}, %{servicesnotrunning}, %{role}, %{requiredservicesrunning} +You can use the following variables: %{servicesrunning}, %{servicesnotrunning}, %{role}, %{requiredservicesrunning} =back diff --git a/src/apps/microsoft/hyperv/2012/local/mode/nodeintegrationservice.pm b/src/apps/microsoft/hyperv/2012/local/mode/nodeintegrationservice.pm index c58feb95b..34f70a6ed 100644 --- a/src/apps/microsoft/hyperv/2012/local/mode/nodeintegrationservice.pm +++ b/src/apps/microsoft/hyperv/2012/local/mode/nodeintegrationservice.pm @@ -307,24 +307,24 @@ Filter virtual machine status (can be a regexp) (Default: 'running'). =item B<--warning-global-status> Set warning threshold for status (Default: '%{integration_service_state} =~ /Update required/i'). -Can used special variables like: %{vm}, %{integration_service_state}, +You can use the following variables: %{vm}, %{integration_service_state}, %{integration_service_version}, %{state} =item B<--critical-global-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{vm}, %{integration_service_state}, +You can use the following variables: %{vm}, %{integration_service_state}, %{integration_service_version}, %{state} =item B<--warning-service-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{vm}, %{service}, %{primary_status}, %{secondary_status}, %{enabled} +You can use the following variables: %{vm}, %{service}, %{primary_status}, %{secondary_status}, %{enabled} =item B<--critical-service-status> Set critical threshold for status (Default: '%{primary_status} !~ /Ok/i'). -Can used special variables like: %{vm}, %{service}, %{primary_status}, %{secondary_status}, %{enabled} +You can use the following variables: %{vm}, %{service}, %{primary_status}, %{secondary_status}, %{enabled} =back diff --git a/src/apps/microsoft/hyperv/2012/local/mode/nodereplication.pm b/src/apps/microsoft/hyperv/2012/local/mode/nodereplication.pm index ddb0f118b..7054ad854 100644 --- a/src/apps/microsoft/hyperv/2012/local/mode/nodereplication.pm +++ b/src/apps/microsoft/hyperv/2012/local/mode/nodereplication.pm @@ -213,12 +213,12 @@ Filter virtual machines (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{health} =~ /Warning/i'). -Can used special variables like: %{vm}, %{state}, %{health} +You can use the following variables: %{vm}, %{state}, %{health} =item B<--critical-status> Set critical threshold for status (Default: '%{health} =~ /Critical/i'). -Can used special variables like: %{vm}, %{state}, %{health} +You can use the following variables: %{vm}, %{state}, %{health} =back diff --git a/src/apps/microsoft/hyperv/2012/local/mode/nodevmstatus.pm b/src/apps/microsoft/hyperv/2012/local/mode/nodevmstatus.pm index 88e5c9b8e..5bdd800af 100644 --- a/src/apps/microsoft/hyperv/2012/local/mode/nodevmstatus.pm +++ b/src/apps/microsoft/hyperv/2012/local/mode/nodevmstatus.pm @@ -226,12 +226,12 @@ Filter by VM notes (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{vm}, %{state}, %{status}, %{is_clustered} +You can use the following variables: %{vm}, %{state}, %{status}, %{is_clustered} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Operating normally/i'). -Can used special variables like: %{vm}, %{state}, %{status}, %{is_clustered} +You can use the following variables: %{vm}, %{state}, %{status}, %{is_clustered} =back diff --git a/src/apps/microsoft/hyperv/2012/local/mode/scvmmintegrationservice.pm b/src/apps/microsoft/hyperv/2012/local/mode/scvmmintegrationservice.pm index 85fd4b5e4..d54b9719c 100644 --- a/src/apps/microsoft/hyperv/2012/local/mode/scvmmintegrationservice.pm +++ b/src/apps/microsoft/hyperv/2012/local/mode/scvmmintegrationservice.pm @@ -355,12 +355,12 @@ Filter hostgroup (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{vm}, %{vmaddition}, %{status} +You can use the following variables: %{vm}, %{vmaddition}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{vmaddition} =~ /not detected/i'). -Can used special variables like: %{vm}, %{vmaddition}, %{status} +You can use the following variables: %{vm}, %{vmaddition}, %{status} =back diff --git a/src/apps/microsoft/hyperv/2012/local/mode/scvmmvmstatus.pm b/src/apps/microsoft/hyperv/2012/local/mode/scvmmvmstatus.pm index 00879b90e..b9bcaf0c3 100644 --- a/src/apps/microsoft/hyperv/2012/local/mode/scvmmvmstatus.pm +++ b/src/apps/microsoft/hyperv/2012/local/mode/scvmmvmstatus.pm @@ -266,12 +266,12 @@ Filter by description (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{vm}, %{status}, %{hostgroup} +You can use the following variables: %{vm}, %{status}, %{hostgroup} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Running|Stopped/i'). -Can used special variables like: %{vm}, %{status}, %{hostgroup} +You can use the following variables: %{vm}, %{status}, %{hostgroup} =back diff --git a/src/apps/microsoft/iis/local/mode/applicationpoolstate.pm b/src/apps/microsoft/iis/local/mode/applicationpoolstate.pm index d136422c7..f15c334e8 100644 --- a/src/apps/microsoft/iis/local/mode/applicationpoolstate.pm +++ b/src/apps/microsoft/iis/local/mode/applicationpoolstate.pm @@ -143,17 +143,17 @@ Filter application pool name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{name}, %{state}, %{auto_start}. +You can use the following variables: %{name}, %{state}, %{auto_start}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{state}, %{auto_start}. +You can use the following variables: %{name}, %{state}, %{auto_start}. =item B<--critical-status> Set critical threshold for status (Default: '%{auto_start} eq "on" and not %{state} =~ /started|starting/'). -Can used special variables like: %{name}, %{state}, %{auto_start}. +You can use the following variables: %{name}, %{state}, %{auto_start}. =back diff --git a/src/apps/microsoft/iis/restapi/mode/applicationpools.pm b/src/apps/microsoft/iis/restapi/mode/applicationpools.pm index 772edf7d1..2dafcec80 100644 --- a/src/apps/microsoft/iis/restapi/mode/applicationpools.pm +++ b/src/apps/microsoft/iis/restapi/mode/applicationpools.pm @@ -133,17 +133,17 @@ Filter application pool name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{auto_start}, %{display} +You can use the following variables: %{status}, %{auto_start}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{auto_start}, %{display} +You can use the following variables: %{status}, %{auto_start}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{auto_start} eq "true" and %{status} !~ /starting|started/'). -Can used special variables like: %{status}, %{auto_start}, %{display} +You can use the following variables: %{status}, %{auto_start}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/microsoft/iis/restapi/mode/websites.pm b/src/apps/microsoft/iis/restapi/mode/websites.pm index 5597855c3..f1fc3b756 100644 --- a/src/apps/microsoft/iis/restapi/mode/websites.pm +++ b/src/apps/microsoft/iis/restapi/mode/websites.pm @@ -169,17 +169,17 @@ Filter website name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /starting|started/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/microsoft/iis/wsman/mode/applicationpools.pm b/src/apps/microsoft/iis/wsman/mode/applicationpools.pm index 58e0e6b7d..22747f285 100644 --- a/src/apps/microsoft/iis/wsman/mode/applicationpools.pm +++ b/src/apps/microsoft/iis/wsman/mode/applicationpools.pm @@ -139,17 +139,17 @@ Filter application pool name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{name}, %{state}, %{auto_start}. +You can use the following variables: %{name}, %{state}, %{auto_start}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{state}, %{auto_start}. +You can use the following variables: %{name}, %{state}, %{auto_start}. =item B<--critical-status> Set critical threshold for status (Default: '%{auto_start} eq "on" and not %{state} =~ /started|starting/'). -Can used special variables like: %{name}, %{state}, %{auto_start}. +You can use the following variables: %{name}, %{state}, %{auto_start}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/microsoft/mscs/local/mode/networkstatus.pm b/src/apps/microsoft/mscs/local/mode/networkstatus.pm index 4a562e497..0ee5d4ee2 100644 --- a/src/apps/microsoft/mscs/local/mode/networkstatus.pm +++ b/src/apps/microsoft/mscs/local/mode/networkstatus.pm @@ -128,17 +128,17 @@ Filter interface name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} =~ /unknown/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: none). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /down|partitioned|unavailable/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =back diff --git a/src/apps/microsoft/mscs/local/mode/nodestatus.pm b/src/apps/microsoft/mscs/local/mode/nodestatus.pm index 60d416f96..c2eaae7b3 100644 --- a/src/apps/microsoft/mscs/local/mode/nodestatus.pm +++ b/src/apps/microsoft/mscs/local/mode/nodestatus.pm @@ -127,17 +127,17 @@ Filter node name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} =~ /unknown/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{state} =~ /pause|joining/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /down/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =back diff --git a/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm b/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm index e3aea281e..40d64f724 100644 --- a/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm +++ b/src/apps/microsoft/mscs/local/mode/resourcegroupstatus.pm @@ -196,17 +196,17 @@ Filter resource group name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} =~ /unknown/'). -Can used special variables like: %{state}, %{display}, %{owner_node} +You can use the following variables: %{state}, %{display}, %{owner_node} =item B<--warning-status> Set warning threshold for status (Default: '%{is_preferred_node} == 0'). -Can used special variables like: %{state}, %{display}, %{owner_node} +You can use the following variables: %{state}, %{display}, %{owner_node} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /failed|offline/'). -Can used special variables like: %{state}, %{display}, %{owner_node} +You can use the following variables: %{state}, %{display}, %{owner_node} =back diff --git a/src/apps/microsoft/mscs/local/mode/resourcestatus.pm b/src/apps/microsoft/mscs/local/mode/resourcestatus.pm index 8870138cd..af823040a 100644 --- a/src/apps/microsoft/mscs/local/mode/resourcestatus.pm +++ b/src/apps/microsoft/mscs/local/mode/resourcestatus.pm @@ -132,17 +132,17 @@ Filter resource name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} =~ /unknown/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: none). -Can used special variables like: %{state}, %{display}, %{owner_node} +You can use the following variables: %{state}, %{display}, %{owner_node} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /failed|offline/'). -Can used special variables like: %{state}, %{display}, %{owner_node} +You can use the following variables: %{state}, %{display}, %{owner_node} =back diff --git a/src/apps/microsoft/sccm/local/mode/databasereplicationstatus.pm b/src/apps/microsoft/sccm/local/mode/databasereplicationstatus.pm index b13db88d6..04b47011b 100644 --- a/src/apps/microsoft/sccm/local/mode/databasereplicationstatus.pm +++ b/src/apps/microsoft/sccm/local/mode/databasereplicationstatus.pm @@ -286,22 +286,22 @@ Print powershell output. =item B<--warning-link-status> Set warning threshold for current synchronisation status (Default: '') -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-link-status> Set critical threshold for current synchronisation status (Default: ''). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-site-status> Set warning threshold for current synchronisation status (Default: '') -Can used special variables like: %{status}, %{type}, %{site_to_site_state}, %{last_sync_time}. +You can use the following variables: %{status}, %{type}, %{site_to_site_state}, %{last_sync_time}. =item B<--critical-site-status> Set critical threshold for current synchronisation status (Default: ''). -Can used special variables like: %{status}, %{type}, %{site_to_site_state}, %{last_sync_time}. +You can use the following variables: %{status}, %{type}, %{site_to_site_state}, %{last_sync_time}. =back diff --git a/src/apps/microsoft/sccm/local/mode/sitestatus.pm b/src/apps/microsoft/sccm/local/mode/sitestatus.pm index dd8efdca0..ffd1776e1 100644 --- a/src/apps/microsoft/sccm/local/mode/sitestatus.pm +++ b/src/apps/microsoft/sccm/local/mode/sitestatus.pm @@ -244,12 +244,12 @@ Print powershell output. =item B<--warning-status> Set warning threshold for current synchronisation status (Default: ''). -Can used special variables like: %{status}, %{mode}, %{type}, %{name}. +You can use the following variables: %{status}, %{mode}, %{type}, %{name}. =item B<--critical-status> Set critical threshold for current synchronisation status (Default: ''). -Can used special variables like: %{status}, %{mode}, %{type}, %{name}. +You can use the following variables: %{status}, %{mode}, %{type}, %{name}. =back diff --git a/src/apps/microsoft/wsus/local/mode/synchronisationstatus.pm b/src/apps/microsoft/wsus/local/mode/synchronisationstatus.pm index 156b85368..0f6bab08f 100644 --- a/src/apps/microsoft/wsus/local/mode/synchronisationstatus.pm +++ b/src/apps/microsoft/wsus/local/mode/synchronisationstatus.pm @@ -374,22 +374,22 @@ Set if WSUS use ssl. =item B<--warning-synchronisation-status> Set warning threshold for current synchronisation status (Default: '') -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-synchronisation-status> Set critical threshold for current synchronisation status (Default: ''). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-last-synchronisation-status> Set warning threshold for current synchronisation status (Default: '') -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-last-synchronisation-status> Set critical threshold for current synchronisation status (Default: '%{status} !~ /Succeeded/'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/monitoring/iplabel/datametrie/restapi/mode/kpi.pm b/src/apps/monitoring/iplabel/datametrie/restapi/mode/kpi.pm index 7150c4fe4..e8b4e0005 100644 --- a/src/apps/monitoring/iplabel/datametrie/restapi/mode/kpi.pm +++ b/src/apps/monitoring/iplabel/datametrie/restapi/mode/kpi.pm @@ -179,17 +179,17 @@ Filter by monitor name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/monitoring/mip/restapi/mode/scenarios.pm b/src/apps/monitoring/mip/restapi/mode/scenarios.pm index 8c4daf5ed..2a765bfed 100644 --- a/src/apps/monitoring/mip/restapi/mode/scenarios.pm +++ b/src/apps/monitoring/mip/restapi/mode/scenarios.pm @@ -322,7 +322,7 @@ Filter scenarios by applicationn name (can be a regexp). =item B<--display-instance> Set the scenario display value (Default: '%{name}'). -Can used special variables like: %{name}, %{app_name}, %{display_name}, %{id} +You can use the following variables: %{name}, %{app_name}, %{display_name}, %{id} =item B<--memory> @@ -331,17 +331,17 @@ Only check new result entries for scenarios. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /critical/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/apps/monitoring/nodeexporter/windows/mode/services.pm b/src/apps/monitoring/nodeexporter/windows/mode/services.pm index ec5c60b8e..1e18deeba 100644 --- a/src/apps/monitoring/nodeexporter/windows/mode/services.pm +++ b/src/apps/monitoring/nodeexporter/windows/mode/services.pm @@ -119,12 +119,12 @@ Default: all services are monitored. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{start_mode} +You can use the following variables: %{status}, %{start_mode} =item B<--critical-status> Set critical threshold for status (Default: '%{start_mode} =~ /auto/ && %{status} !~ /^running$/'). -Can used special variables like: %{status}, %{start_mode} +You can use the following variables: %{status}, %{start_mode} =back diff --git a/src/apps/monitoring/ntopng/restapi/mode/alerts.pm b/src/apps/monitoring/ntopng/restapi/mode/alerts.pm index 44053cb69..9b78f3cc1 100644 --- a/src/apps/monitoring/ntopng/restapi/mode/alerts.pm +++ b/src/apps/monitoring/ntopng/restapi/mode/alerts.pm @@ -215,12 +215,12 @@ Can be: 'last-5mns' (default), 'last-hour' =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor/i') -Can used special variables like: %{severity}, %{type}, %{timeraised} +You can use the following variables: %{severity}, %{type}, %{timeraised} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /major|critical/i'). -Can used special variables like: %{severity}, %{type}, %{timeraised} +You can use the following variables: %{severity}, %{type}, %{timeraised} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/monitoring/scom/restapi/mode/alerts.pm b/src/apps/monitoring/scom/restapi/mode/alerts.pm index 20ed9f801..a2220dbe0 100644 --- a/src/apps/monitoring/scom/restapi/mode/alerts.pm +++ b/src/apps/monitoring/scom/restapi/mode/alerts.pm @@ -169,12 +169,12 @@ Filter by host name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning/i') -Can used special variables like: %{severity}, %{host}, %{name}, %{timeraised} +You can use the following variables: %{severity}, %{host}, %{name}, %{timeraised} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical/i'). -Can used special variables like: %{severity}, %{host}, %{name}, %{timeraised} +You can use the following variables: %{severity}, %{host}, %{name}, %{timeraised} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/activemq/jmx/mode/brokers.pm b/src/apps/mq/activemq/jmx/mode/brokers.pm index e1ba743e5..463db4b03 100644 --- a/src/apps/mq/activemq/jmx/mode/brokers.pm +++ b/src/apps/mq/activemq/jmx/mode/brokers.pm @@ -321,12 +321,12 @@ Filter destination type (Can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Good/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/ibmmq/mqi/mode/channels.pm b/src/apps/mq/ibmmq/mqi/mode/channels.pm index 213dc4132..4f23da6d7 100644 --- a/src/apps/mq/ibmmq/mqi/mode/channels.pm +++ b/src/apps/mq/ibmmq/mqi/mode/channels.pm @@ -212,17 +212,17 @@ MQTT - Telemetry =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{channel_status}, %{mca_status} +You can use the following variables: %{channel_status}, %{mca_status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{channel_status}, %{mca_status} +You can use the following variables: %{channel_status}, %{mca_status} =item B<--critical-status> Set critical threshold for status (Default: '%{channel_status} !~ /running|idle/i'). -Can used special variables like: %{channel_status}, %{mca_status} +You can use the following variables: %{channel_status}, %{mca_status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/ibmmq/mqi/mode/queuemanager.pm b/src/apps/mq/ibmmq/mqi/mode/queuemanager.pm index 5e2680095..de1c4f3f6 100644 --- a/src/apps/mq/ibmmq/mqi/mode/queuemanager.pm +++ b/src/apps/mq/ibmmq/mqi/mode/queuemanager.pm @@ -135,17 +135,17 @@ Check queue manager. =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{mgr_status}, %{channel_initiator_status}, %{command_server_status} +You can use the following variables: %{mgr_status}, %{channel_initiator_status}, %{command_server_status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{mgr_status}, %{channel_initiator_status}, %{command_server_status} +You can use the following variables: %{mgr_status}, %{channel_initiator_status}, %{command_server_status} =item B<--critical-status> Set critical threshold for status (Default: '%{mgr_status} !~ /running/i'). -Can used special variables like: %{mgr_status}, %{channel_initiator_status}, %{command_server_status} +You can use the following variables: %{mgr_status}, %{channel_initiator_status}, %{command_server_status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/ibmmq/restapi/mode/queuemanagers.pm b/src/apps/mq/ibmmq/restapi/mode/queuemanagers.pm index c3a60de4e..4c41bd1fd 100644 --- a/src/apps/mq/ibmmq/restapi/mode/queuemanagers.pm +++ b/src/apps/mq/ibmmq/restapi/mode/queuemanagers.pm @@ -147,17 +147,17 @@ Filter queue managers by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{mgr_status}, %{channel_initiator_status} +You can use the following variables: %{mgr_status}, %{channel_initiator_status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{mgr_status}, %{channel_initiator_status} +You can use the following variables: %{mgr_status}, %{channel_initiator_status} =item B<--critical-status> Set critical threshold for status (Default: '%{mgr_status} !~ /running/i'). -Can used special variables like: %{mgr_status}, %{channel_initiator_status} +You can use the following variables: %{mgr_status}, %{channel_initiator_status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/rabbitmq/restapi/mode/nodeusage.pm b/src/apps/mq/rabbitmq/restapi/mode/nodeusage.pm index 8376956e6..2b34328d3 100644 --- a/src/apps/mq/rabbitmq/restapi/mode/nodeusage.pm +++ b/src/apps/mq/rabbitmq/restapi/mode/nodeusage.pm @@ -142,12 +142,12 @@ Filter node name (Can use regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "running"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/rabbitmq/restapi/mode/queueusage.pm b/src/apps/mq/rabbitmq/restapi/mode/queueusage.pm index 574023446..1d65c7da9 100644 --- a/src/apps/mq/rabbitmq/restapi/mode/queueusage.pm +++ b/src/apps/mq/rabbitmq/restapi/mode/queueusage.pm @@ -143,12 +143,12 @@ Filter queue name (Can use regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "running"'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/rabbitmq/restapi/mode/vhostusage.pm b/src/apps/mq/rabbitmq/restapi/mode/vhostusage.pm index 761b22866..cba8eec37 100644 --- a/src/apps/mq/rabbitmq/restapi/mode/vhostusage.pm +++ b/src/apps/mq/rabbitmq/restapi/mode/vhostusage.pm @@ -142,12 +142,12 @@ Filter vhost name (Can use regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "ok"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/vernemq/restapi/mode/clusters.pm b/src/apps/mq/vernemq/restapi/mode/clusters.pm index 7102dda55..848e8b5e5 100644 --- a/src/apps/mq/vernemq/restapi/mode/clusters.pm +++ b/src/apps/mq/vernemq/restapi/mode/clusters.pm @@ -143,17 +143,17 @@ Filter cluster name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "notRunning"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/mq/vernemq/restapi/mode/listeners.pm b/src/apps/mq/vernemq/restapi/mode/listeners.pm index 47813bffe..6db20a18d 100644 --- a/src/apps/mq/vernemq/restapi/mode/listeners.pm +++ b/src/apps/mq/vernemq/restapi/mode/listeners.pm @@ -143,17 +143,17 @@ Filter listener type (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "running"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/openweathermap/restapi/mode/cityweather.pm b/src/apps/openweathermap/restapi/mode/cityweather.pm index 2e493e19b..3227f457e 100644 --- a/src/apps/openweathermap/restapi/mode/cityweather.pm +++ b/src/apps/openweathermap/restapi/mode/cityweather.pm @@ -156,12 +156,12 @@ City name (e.g London or ISO 3166 code like London,uk) =item B<--warning-weather> Set warning threshold for weather string desc (Default: ''). -Can used special variables like: %{weather} +You can use the following variables: %{weather} =item B<--critical-weather> Set critical threshold for weather string desc (Default: ''). -Can used special variables like: %{weather} +You can use the following variables: %{weather} Example : --critical-weather='%{weather} eq "Clouds' diff --git a/src/apps/oracle/gg/local/mode/processes.pm b/src/apps/oracle/gg/local/mode/processes.pm index 6ef54a9c3..459527a2e 100644 --- a/src/apps/oracle/gg/local/mode/processes.pm +++ b/src/apps/oracle/gg/local/mode/processes.pm @@ -187,17 +187,17 @@ Filter processes by type (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name}, %{group}, %{type} +You can use the following variables: %{status}, %{name}, %{group}, %{type} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{group}, %{type} +You can use the following variables: %{status}, %{name}, %{group}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /ABENDED/i'). -Can used special variables like: %{status}, %{name}, %{group}, %{type} +You can use the following variables: %{status}, %{name}, %{group}, %{type} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/oracle/ovm/api/mode/manager.pm b/src/apps/oracle/ovm/api/mode/manager.pm index cc001ed4a..582c1ba22 100644 --- a/src/apps/oracle/ovm/api/mode/manager.pm +++ b/src/apps/oracle/ovm/api/mode/manager.pm @@ -137,17 +137,17 @@ Example: --filter-counters='status' =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /running/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/oracle/ovm/api/mode/servers.pm b/src/apps/oracle/ovm/api/mode/servers.pm index d28d30d9e..2444ac2ff 100644 --- a/src/apps/oracle/ovm/api/mode/servers.pm +++ b/src/apps/oracle/ovm/api/mode/servers.pm @@ -206,17 +206,17 @@ Filter servers by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{running_status}, %{is_maintenance}, %{up2date}, %{name} +You can use the following variables: %{running_status}, %{is_maintenance}, %{up2date}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{running_status}, %{is_maintenance}, %{up2date}, %{name} +You can use the following variables: %{running_status}, %{is_maintenance}, %{up2date}, %{name} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{running_status}, %{is_maintenance}, %{up2date}, %{name} +You can use the following variables: %{running_status}, %{is_maintenance}, %{up2date}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/oracle/ovm/api/mode/vm.pm b/src/apps/oracle/ovm/api/mode/vm.pm index d4847ebaf..53d113c44 100644 --- a/src/apps/oracle/ovm/api/mode/vm.pm +++ b/src/apps/oracle/ovm/api/mode/vm.pm @@ -155,17 +155,17 @@ Filter virtual machines by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{running_status}, %{name} +You can use the following variables: %{running_status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{running_status}, %{name} +You can use the following variables: %{running_status}, %{name} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{running_status}, %{name} +You can use the following variables: %{running_status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/pacemaker/local/mode/crm.pm b/src/apps/pacemaker/local/mode/crm.pm index f7af49afa..d322d9f95 100644 --- a/src/apps/pacemaker/local/mode/crm.pm +++ b/src/apps/pacemaker/local/mode/crm.pm @@ -470,42 +470,42 @@ Filter resource (also clone resource) by name (can be a regexp). =item B<--warning-connection-status> Set warning threshold for status. -Can used special variables like: %{connection_status}, %{connection_error} +You can use the following variables: %{connection_status}, %{connection_error} =item B<--critical-connection-status> Set critical threshold for status (Default: '%{connection_status} =~ /failed/i'). -Can used special variables like: %{connection_status}, %{connection_error} +You can use the following variables: %{connection_status}, %{connection_error} =item B<--warning-quorum-status> Set warning threshold for status. -Can used special variables like: %{quorum_status} +You can use the following variables: %{quorum_status} =item B<--critical-quorum-status> Set critical threshold for status (Default: '%{quorum_status} =~ /noQuorum/i'). -Can used special variables like: %{quorum_status} +You can use the following variables: %{quorum_status} =item B<--warning-resource-status> Set warning threshold for status. -Can used special variables like: %{name}, %{status}, %{node}, %{is_unmanaged} +You can use the following variables: %{name}, %{status}, %{node}, %{is_unmanaged} =item B<--critical-resource-status> Set critical threshold for status (Default: '%{status} =~ /stopped|failed/i'). -Can used special variables like: %{name}, %{status}, %{node}, %{is_unmanaged} +You can use the following variables: %{name}, %{status}, %{node}, %{is_unmanaged} =item B<--warning-clone-resource-status> Set warning threshold for status. -Can used special variables like: %{name}, %{status}, %{masters_nodes_name}, %{slaves_nodes_name}, %{is_unmanaged} +You can use the following variables: %{name}, %{status}, %{masters_nodes_name}, %{slaves_nodes_name}, %{is_unmanaged} =item B<--critical-clone-resource-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{name}, %{status}, %{masters_nodes_name}, %{slaves_nodes_name}, %{is_unmanaged} +You can use the following variables: %{name}, %{status}, %{masters_nodes_name}, %{slaves_nodes_name}, %{is_unmanaged} =item B<--ignore-failed-actions> diff --git a/src/apps/pfsense/fauxapi/mode/gateways.pm b/src/apps/pfsense/fauxapi/mode/gateways.pm index 1076de57e..e2fa8bffd 100644 --- a/src/apps/pfsense/fauxapi/mode/gateways.pm +++ b/src/apps/pfsense/fauxapi/mode/gateways.pm @@ -147,17 +147,17 @@ Filter gateway name (can be a regexp). =item B<--unknown-status> Set unknon threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /none/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/pineapp/securemail/snmp/mode/system.pm b/src/apps/pineapp/securemail/snmp/mode/system.pm index 0f5043b2a..53ddd7001 100644 --- a/src/apps/pineapp/securemail/snmp/mode/system.pm +++ b/src/apps/pineapp/securemail/snmp/mode/system.pm @@ -234,32 +234,32 @@ Check system usage. =item B<--unknown-service-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-service-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-service-status> Set critical threshold for status (Default: '%{status} !~ /running/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--unknown-storage-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-storage-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-storage-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/protocols/cifs/mode/connection.pm b/src/apps/protocols/cifs/mode/connection.pm index e11a46f41..07eb70022 100644 --- a/src/apps/protocols/cifs/mode/connection.pm +++ b/src/apps/protocols/cifs/mode/connection.pm @@ -109,12 +109,12 @@ Set the share directory. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--critical-status> Set critical threshold for status (Default: '%{message} !~ /authentication succeeded/i' -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--warning-time> diff --git a/src/apps/protocols/cifs/mode/scenario.pm b/src/apps/protocols/cifs/mode/scenario.pm index 8b6368eff..95aa74224 100644 --- a/src/apps/protocols/cifs/mode/scenario.pm +++ b/src/apps/protocols/cifs/mode/scenario.pm @@ -303,22 +303,22 @@ Can be a file or json content. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "success"') -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-step-status> Set warning threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--critical-step-status> Set critical threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/protocols/http/mode/expectedcontent.pm b/src/apps/protocols/http/mode/expectedcontent.pm index dfe631ece..6601f6e0b 100644 --- a/src/apps/protocols/http/mode/expectedcontent.pm +++ b/src/apps/protocols/http/mode/expectedcontent.pm @@ -357,17 +357,17 @@ Threshold critical for extracted value =item B<--unknown-content> Set warning threshold for content page (Default: ''). -Can used special variables like: %{content}, %{header}, %{first_header}, %{code} +You can use the following variables: %{content}, %{header}, %{first_header}, %{code} =item B<--warning-content> Set warning threshold for status (Default: ''). -Can used special variables like: %{content}, %{header}, %{first_header}, %{code} +You can use the following variables: %{content}, %{header}, %{first_header}, %{code} =item B<--critical-content> Set critical threshold for content page (Default: ''). -Can used special variables like: %{content}, %{header}, %{first_header}, %{code} +You can use the following variables: %{content}, %{header}, %{first_header}, %{code} =back diff --git a/src/apps/protocols/http/mode/jsoncontent.pm b/src/apps/protocols/http/mode/jsoncontent.pm index bb8170fd0..5c9c82032 100644 --- a/src/apps/protocols/http/mode/jsoncontent.pm +++ b/src/apps/protocols/http/mode/jsoncontent.pm @@ -415,23 +415,26 @@ Override all the format options but substitute are still applied. =item B<--format-ok> -Output format (Default: '%{count} element(s) found') -Can used: +Customize the format of the output when the status is OK (Default: '%{count} element(s) found') +You can use the following variables: '%{values}' = display all values (also text string) '%{values_ok}' = values from attributes and text node only (seperated by option values-separator) '%{values_warning}' and '%{values_critical}' =item B<--format-warning> -Output warning format (Default: %{count} element(s) found') +Customize the format of the output when the status is WARNING (Default: '%{count} element(s) found') +You can use the variables described in --format-ok =item B<--format-critical> -Output critical format (Default: %{count} element(s) found') +Customize the format of the output when the status is CRITICAL (Default: '%{count} element(s) found') +You can use the variables described in --format-ok =item B<--format-unknown> -Output unknown format (Default: %{count} element(s) found') +Customize the format of the output when the status is UNKNOWN (Default: '%{count} element(s) found') +You can use the variables described in --format-ok =item B<--values-separator> diff --git a/src/apps/protocols/http/mode/soapcontent.pm b/src/apps/protocols/http/mode/soapcontent.pm index a2ca8e11a..334fed7da 100644 --- a/src/apps/protocols/http/mode/soapcontent.pm +++ b/src/apps/protocols/http/mode/soapcontent.pm @@ -347,19 +347,21 @@ FORMAT OPTIONS: =item B<--format-ok> -Output format (Default: '%{count} element(s) found') -Can used: +Customize the format of the output when the status is OK (Default: '%{count} element(s) found') +You can use the following variables: '%{values}' = display all values (also text string) '%{values_ok}' = values from attributes and text node only (seperated by option values-separator) '%{values_warning}' and '%{values_critical}' =item B<--format-warning> -Output warning format (Default: %{count} element(s) found') +Customize the format of the output when the status is WARNING (Default: '%{count} element(s) found') +You can use the variables described in --format-ok =item B<--format-critical> -Output critical format (Default: %{count} element(s) found') +Customize the format of the output when the status is CRITICAL (Default: '%{count} element(s) found') +You can use the variables described in --format-ok =item B<--values-separator> diff --git a/src/apps/protocols/ospf/snmp/mode/neighbor.pm b/src/apps/protocols/ospf/snmp/mode/neighbor.pm index 56eea2c0a..7d5cb9d45 100644 --- a/src/apps/protocols/ospf/snmp/mode/neighbor.pm +++ b/src/apps/protocols/ospf/snmp/mode/neighbor.pm @@ -169,12 +169,12 @@ Example: --filter-counters='^status$' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{NbrState}, %{NbrRtrId}, %{NbrIpAddr} +You can use the following variables: %{NbrState}, %{NbrRtrId}, %{NbrIpAddr} =item B<--critical-status> Set critical threshold for status (Default: '%{NbrState} =~ /down/i'). -Can used special variables like: %{NbrState}, %{NbrRtrId}, %{NbrIpAddr} +You can use the following variables: %{NbrState}, %{NbrRtrId}, %{NbrIpAddr} =item B<--warning-total-change> diff --git a/src/apps/protocols/radius/mode/login.pm b/src/apps/protocols/radius/mode/login.pm index 82cafdd9c..99eb24d75 100644 --- a/src/apps/protocols/radius/mode/login.pm +++ b/src/apps/protocols/radius/mode/login.pm @@ -268,12 +268,12 @@ Set radius-dictionary file (mandatory with --radius-attribute) (multiple option) =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{error_msg}, %{attributes}. +You can use the following variables: %{status}, %{error_msg}, %{attributes}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "accepted"'). -Can used special variables like: %{status}, %{error_msg}, %{attributes}. +You can use the following variables: %{status}, %{error_msg}, %{attributes}. =item B<--warning-time> diff --git a/src/apps/protocols/sftp/mode/connection.pm b/src/apps/protocols/sftp/mode/connection.pm index fae71a539..f17dde925 100644 --- a/src/apps/protocols/sftp/mode/connection.pm +++ b/src/apps/protocols/sftp/mode/connection.pm @@ -99,12 +99,12 @@ Check sftp connection. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--critical-status> Set critical threshold for status (Default: '%{message} !~ /authentication succeeded/i' -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--warning-time> diff --git a/src/apps/protocols/sftp/mode/scenario.pm b/src/apps/protocols/sftp/mode/scenario.pm index d634cc6b5..47edf2c3d 100644 --- a/src/apps/protocols/sftp/mode/scenario.pm +++ b/src/apps/protocols/sftp/mode/scenario.pm @@ -310,22 +310,22 @@ Can be a file or json content. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "success"') -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-step-status> Set warning threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--critical-step-status> Set critical threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/protocols/ssh/mode/login.pm b/src/apps/protocols/ssh/mode/login.pm index 2068bc488..e6fc1a9d8 100644 --- a/src/apps/protocols/ssh/mode/login.pm +++ b/src/apps/protocols/ssh/mode/login.pm @@ -95,12 +95,12 @@ Check SSH connection. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--critical-status> Set critical threshold for status (Default: '%{message} !~ /authentication succeeded/i' -Can used special variables like: %{status}, %{message} +You can use the following variables: %{status}, %{message} =item B<--warning-time> diff --git a/src/apps/protocols/tcp/mode/connectionstatus.pm b/src/apps/protocols/tcp/mode/connectionstatus.pm index fd497f024..3e72de159 100644 --- a/src/apps/protocols/tcp/mode/connectionstatus.pm +++ b/src/apps/protocols/tcp/mode/connectionstatus.pm @@ -182,17 +182,17 @@ Connection timeout in seconds (Default: 3) =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{port}, %{error_message} +You can use the following variables: %{status}, %{port}, %{error_message} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{port}, %{error_message} +You can use the following variables: %{status}, %{port}, %{error_message} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "failed"'). -Can used special variables like: %{status}, %{port}, %{error_message} +You can use the following variables: %{status}, %{port}, %{error_message} =item B<--warning-time> diff --git a/src/apps/protocols/tftp/mode/commands.pm b/src/apps/protocols/tftp/mode/commands.pm index 87d35063c..0d2c412c7 100644 --- a/src/apps/protocols/tftp/mode/commands.pm +++ b/src/apps/protocols/tftp/mode/commands.pm @@ -236,12 +236,12 @@ Example: --filter-counters='^status$' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "ok"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-time> diff --git a/src/apps/protocols/whois/mode/domain.pm b/src/apps/protocols/whois/mode/domain.pm index a8ab7a103..81f9b0e06 100644 --- a/src/apps/protocols/whois/mode/domain.pm +++ b/src/apps/protocols/whois/mode/domain.pm @@ -430,17 +430,17 @@ Set your domain expiration date timezone (default: 'UTC'). =item B<--unknown-status> Set critical threshold for status (Default: '%{status} =~ /checkError/i'). -Can used special variables like: %{status}, %{domain} +You can use the following variables: %{status}, %{domain} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{domain} +You can use the following variables: %{status}, %{domain} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{domain} +You can use the following variables: %{status}, %{domain} =item B<--unit> diff --git a/src/apps/proxmox/mg/restapi/mode/version.pm b/src/apps/proxmox/mg/restapi/mode/version.pm index 6f76e98fe..51db5c930 100644 --- a/src/apps/proxmox/mg/restapi/mode/version.pm +++ b/src/apps/proxmox/mg/restapi/mode/version.pm @@ -96,12 +96,12 @@ Check version. =item B<--warning-version> Set warning threshold for version. -Can used special variables like: %{version}, %{repoid}, %{release} +You can use the following variables: %{version}, %{repoid}, %{release} =item B<--critical-version> Set critical threshold for version. -Can used special variables like: %{version}, %{repoid}, %{release} +You can use the following variables: %{version}, %{repoid}, %{release} =back diff --git a/src/apps/proxmox/ve/restapi/mode/nodeusage.pm b/src/apps/proxmox/ve/restapi/mode/nodeusage.pm index 88f338631..aa402c88a 100644 --- a/src/apps/proxmox/ve/restapi/mode/nodeusage.pm +++ b/src/apps/proxmox/ve/restapi/mode/nodeusage.pm @@ -369,12 +369,12 @@ Can be: 'cpu' (%), 'memory' (%), 'swap' (%), 'fs' (%). =item B<--warning-node-status> Set warning threshold for status. -Can used special variables like: %{name}, %{state}. +You can use the following variables: %{name}, %{state}. =item B<--critical-node-status> Set critical threshold for status. -Can used special variables like: %{name}, %{state}. +You can use the following variables: %{name}, %{state}. =back diff --git a/src/apps/proxmox/ve/restapi/mode/storageusage.pm b/src/apps/proxmox/ve/restapi/mode/storageusage.pm index d23d3e9b2..f7dfccfad 100644 --- a/src/apps/proxmox/ve/restapi/mode/storageusage.pm +++ b/src/apps/proxmox/ve/restapi/mode/storageusage.pm @@ -237,12 +237,12 @@ Exact node name. =item B<--warning-storage-status> Set warning threshold for status. -Can used special variables like: %{name}, %{state}. +You can use the following variables: %{name}, %{state}. =item B<--critical-storage-status> Set critical threshold for status. -Can used special variables like: %{name}, %{state}. +You can use the following variables: %{name}, %{state}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/proxmox/ve/restapi/mode/vmusage.pm b/src/apps/proxmox/ve/restapi/mode/vmusage.pm index 0cf38970a..29f134231 100644 --- a/src/apps/proxmox/ve/restapi/mode/vmusage.pm +++ b/src/apps/proxmox/ve/restapi/mode/vmusage.pm @@ -350,12 +350,12 @@ Can be: 'read-iops', 'write-iops', 'traffic-in', 'traffic-out', =item B<--warning-vm-status> Set warning threshold for status (Default: -) -Can used special variables like: %{name}, %{state}. +You can use the following variables: %{name}, %{state}. =item B<--critical-vm-status> Set critical threshold for status (Default: -). -Can used special variables like: %{name}, %{state}. +You can use the following variables: %{name}, %{state}. =back diff --git a/src/apps/redis/rlec/restapi/mode/databasesstats.pm b/src/apps/redis/rlec/restapi/mode/databasesstats.pm index ad9de77bb..437ce0ef8 100644 --- a/src/apps/redis/rlec/restapi/mode/databasesstats.pm +++ b/src/apps/redis/rlec/restapi/mode/databasesstats.pm @@ -529,7 +529,7 @@ Example: --filter-counters='rate|latency' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{type}, +You can use the following variables: %{status}, %{type}, %{backup_status}, %{export_status}, %{shard_list}. 'status' can be: 'pending', 'active', 'active-change-pending', 'delete-pending', 'import-pending', 'creation-failed', 'recovery'. @@ -544,7 +544,7 @@ Can used special variables like: %{status}, %{type}, Set critical threshold for status (Default: '%{status} =~ /creation-failed/i | %{backup_status} =~ /failed/i | %{export_status} =~ /failed/i | %{import_status} =~ /failed/i'). -Can used special variables like: %{status}, %{type}, +You can use the following variables: %{status}, %{type}, %{backup_status}, %{export_status}, %{shard_list}. 'status' can be: 'pending', 'active', 'active-change-pending', 'delete-pending', 'import-pending', 'creation-failed', 'recovery'. diff --git a/src/apps/redis/rlec/restapi/mode/nodesstats.pm b/src/apps/redis/rlec/restapi/mode/nodesstats.pm index 029c922a8..26d602395 100644 --- a/src/apps/redis/rlec/restapi/mode/nodesstats.pm +++ b/src/apps/redis/rlec/restapi/mode/nodesstats.pm @@ -361,7 +361,7 @@ Thresholds are on free space left. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{shard_list}, +You can use the following variables: %{status}, %{shard_list}, %{int_addr}, %{ext_addr}. 'status' can be: 'active', 'going_offline', 'offline', 'provisioning', 'decommissioning', 'down'. @@ -369,7 +369,7 @@ Can used special variables like: %{status}, %{shard_list}, =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{shard_list}, +You can use the following variables: %{status}, %{shard_list}, %{int_addr}, %{ext_addr}. 'status' can be: 'active', 'going_offline', 'offline', 'provisioning', 'decommissioning', 'down'. diff --git a/src/apps/redis/rlec/restapi/mode/shardsstats.pm b/src/apps/redis/rlec/restapi/mode/shardsstats.pm index 3fffdc12c..2322cc6f4 100644 --- a/src/apps/redis/rlec/restapi/mode/shardsstats.pm +++ b/src/apps/redis/rlec/restapi/mode/shardsstats.pm @@ -374,7 +374,7 @@ Example: --filter-counters='clients' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{detailed_status}, +You can use the following variables: %{status}, %{detailed_status}, %{role}, %{loading}, %{sync}, %{backup}. 'status' can be: 'active', 'inactive', 'trimming'. 'detailed_status' can be: 'ok', 'importing', 'timeout', @@ -388,7 +388,7 @@ Can used special variables like: %{status}, %{detailed_status}, Set critical threshold for status (Default: '%{status} =~ /inactive/i || %{backup} =~ /failed/i || %{sync} =~ /link_down/i'). -Can used special variables like: %{status}, %{detailed_status}, +You can use the following variables: %{status}, %{detailed_status}, %{role}, %{loading}, %{sync}, %{backup}. 'status' can be: 'active', 'inactive', 'trimming'. 'detailed_status' can be: 'ok', 'importing', 'timeout', diff --git a/src/apps/redis/sentinel/mode/redisclusters.pm b/src/apps/redis/sentinel/mode/redisclusters.pm index 4ef28a932..4fe01198b 100644 --- a/src/apps/redis/sentinel/mode/redisclusters.pm +++ b/src/apps/redis/sentinel/mode/redisclusters.pm @@ -240,17 +240,17 @@ Filter clusters by name (Can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{role}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{role}, %{address}, %{port}, %{cluster_name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{role}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{role}, %{address}, %{port}, %{cluster_name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /o_down|s_down|master_down|disconnected/i'). -Can used special variables like: %{status}, %{role}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{role}, %{address}, %{port}, %{cluster_name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/redis/sentinel/mode/sentinelclusters.pm b/src/apps/redis/sentinel/mode/sentinelclusters.pm index 7b1c831ed..d00b47ad3 100644 --- a/src/apps/redis/sentinel/mode/sentinelclusters.pm +++ b/src/apps/redis/sentinel/mode/sentinelclusters.pm @@ -219,32 +219,32 @@ Filter clusters by name (Can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{address}, %{port}, %{cluster_name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{address}, %{port}, %{cluster_name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /o_down|s_down|master_down|disconnected/i'). -Can used special variables like: %{status}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{address}, %{port}, %{cluster_name} =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{address}, %{port}, %{cluster_name} =item B<--warning-quorum-status> Set warning threshold for quorum status. -Can used special variables like: %{status}, %{address}, %{port}, %{cluster_name} +You can use the following variables: %{status}, %{address}, %{port}, %{cluster_name} =item B<--critical-quorum-status> Set critical threshold for quorum status (Default: '%{status} =~ /noQuorum/'). -Can used special variables like: %{status}, %{cluster_name} +You can use the following variables: %{status}, %{cluster_name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/rudder/restapi/mode/globalcompliance.pm b/src/apps/rudder/restapi/mode/globalcompliance.pm index 296f1fcef..769d30b50 100644 --- a/src/apps/rudder/restapi/mode/globalcompliance.pm +++ b/src/apps/rudder/restapi/mode/globalcompliance.pm @@ -148,12 +148,12 @@ Set critical threshold on global compliance. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{detail}, %{value} +You can use the following variables: %{detail}, %{value} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{detail}, %{value} +You can use the following variables: %{detail}, %{value} Example : --critical-status='%{detail} eq "error" && %{value} > 5' diff --git a/src/apps/rudder/restapi/mode/nodecompliance.pm b/src/apps/rudder/restapi/mode/nodecompliance.pm index 9a84ead67..8402c7965 100644 --- a/src/apps/rudder/restapi/mode/nodecompliance.pm +++ b/src/apps/rudder/restapi/mode/nodecompliance.pm @@ -176,12 +176,12 @@ Set critical threshold on node compliance. =item B<--warning-status> Set warning threshold for status of rule compliance (Default: ''). -Can used special variables like: %{rule}, %{compliance} +You can use the following variables: %{rule}, %{compliance} =item B<--critical-status> Set critical threshold for status of rule compliance (Default: ''). -Can used special variables like: %{rule}, %{compliance} +You can use the following variables: %{rule}, %{compliance} Example : --critical-status='%{rule} eq "Global configuration for all nodes" && %{compliance} < 95' diff --git a/src/apps/rudder/restapi/mode/rulecompliance.pm b/src/apps/rudder/restapi/mode/rulecompliance.pm index 0dc24de4d..aee7dba4f 100644 --- a/src/apps/rudder/restapi/mode/rulecompliance.pm +++ b/src/apps/rudder/restapi/mode/rulecompliance.pm @@ -182,12 +182,12 @@ Set critical threshold on rule compliance. =item B<--warning-status> Set warning threshold for status of directive compliance (Default: ''). -Can used special variables like: %{directive}, %{compliance} +You can use the following variables: %{directive}, %{compliance} =item B<--critical-status> Set critical threshold for status of directive compliance (Default: ''). -Can used special variables like: %{directive}, %{compliance} +You can use the following variables: %{directive}, %{compliance} Example : --critical-status='%{directive} eq "Users" && %{compliance} < 85' diff --git a/src/apps/sahipro/restapi/mode/scenario.pm b/src/apps/sahipro/restapi/mode/scenario.pm index acdf70801..238354f08 100644 --- a/src/apps/sahipro/restapi/mode/scenario.pm +++ b/src/apps/sahipro/restapi/mode/scenario.pm @@ -525,12 +525,12 @@ Threshold critical for running scenario rest api response. =item B<--warning-status> Set warning threshold for scenario status. -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-status> Set critical threshold for scenario status (Default: '%{status} ne "SUCCESS"'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-*> B<--critical-*> diff --git a/src/apps/smartermail/restapi/mode/licenses.pm b/src/apps/smartermail/restapi/mode/licenses.pm index a1b71e4db..c113bc51a 100644 --- a/src/apps/smartermail/restapi/mode/licenses.pm +++ b/src/apps/smartermail/restapi/mode/licenses.pm @@ -92,17 +92,17 @@ Check licenses. =item B<--unknown-upgrade-protection-status> Set unknown threshold for status. -Can used special variables like: %{upgrade_protection_status} +You can use the following variables: %{upgrade_protection_status} =item B<--warning-upgrade-protection-status> Set warning threshold for status. -Can used special variables like: %{upgrade_protection_status} +You can use the following variables: %{upgrade_protection_status} =item B<--critical-upgrade-protection-status> Set critical threshold for status (Default: '%{upgrade_protection_status} =~ /expired/'). -Can used special variables like: %{upgrade_protection_status} +You can use the following variables: %{upgrade_protection_status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/smartermail/restapi/mode/services.pm b/src/apps/smartermail/restapi/mode/services.pm index 1d001d505..82e836edd 100644 --- a/src/apps/smartermail/restapi/mode/services.pm +++ b/src/apps/smartermail/restapi/mode/services.pm @@ -108,17 +108,17 @@ Only display some counters (regexp can be used). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /running/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =back diff --git a/src/apps/thales/mistral/vs9/restapi/mode/clusters.pm b/src/apps/thales/mistral/vs9/restapi/mode/clusters.pm index 75fb123dd..5d63ea28f 100644 --- a/src/apps/thales/mistral/vs9/restapi/mode/clusters.pm +++ b/src/apps/thales/mistral/vs9/restapi/mode/clusters.pm @@ -291,32 +291,32 @@ Filter clusters by name. =item B<--unknown-cluster-status> Set unknown threshold for status. -Can used special variables like: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName} +You can use the following variables: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName} =item B<--warning-cluster-status> Set warning threshold for status (Default: '%{gatewaysClusterStatus} =~ /HAC_FAILOVER/i'). -Can used special variables like: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName} +You can use the following variables: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName} =item B<--critical-cluster-status> Set critical threshold for status (Default: '%{gatewaysClusterStatus} =~ /HAC_FAILURE|HAC_DOWN|HAC_BACKUP_FAILURE/i'). -Can used special variables like: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName} +You can use the following variables: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName} =item B<--unknown-member-status> Set unknown threshold for status. -Can used special variables like: %{connectedStatus}, %{role}, %{memberName} +You can use the following variables: %{connectedStatus}, %{role}, %{memberName} =item B<--warning-member-status> Set warning threshold for status. -Can used special variables like: %{connectedStatus}, %{role}, %{memberName} +You can use the following variables: %{connectedStatus}, %{role}, %{memberName} =item B<--critical-member-status> Set critical threshold for status. -Can used special variables like: %{connectedStatus}, %{role}, %{memberName} +You can use the following variables: %{connectedStatus}, %{role}, %{memberName} =item B<--time-contact-unit> diff --git a/src/apps/thales/mistral/vs9/restapi/mode/devices.pm b/src/apps/thales/mistral/vs9/restapi/mode/devices.pm index b966b521a..ac69c7712 100644 --- a/src/apps/thales/mistral/vs9/restapi/mode/devices.pm +++ b/src/apps/thales/mistral/vs9/restapi/mode/devices.pm @@ -957,122 +957,122 @@ Check tunnels. =item B<--unknown-certificate-status> Set unknown threshold for status. -Can used special variables like: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName} +You can use the following variables: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName} =item B<--warning-certificate-status> Set warning threshold for status. -Can used special variables like: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName} +You can use the following variables: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName} =item B<--critical-certificate-status> Set critical threshold for status. -Can used special variables like: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName} +You can use the following variables: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName} =item B<--unknown-connection-status> Set unknown threshold for status (Default: '%{connectionStatus} =~ /unknown/i'). -Can used special variables like: %{sn}, %{connectionStatus} +You can use the following variables: %{sn}, %{connectionStatus} =item B<--warning-connection-status> Set warning threshold for status (Default: '%{connectionStatus} =~ /disconnected|unpaired/i'). -Can used special variables like: %{sn}, %{connectionStatus} +You can use the following variables: %{sn}, %{connectionStatus} =item B<--critical-connection-status> Set critical threshold for status. -Can used special variables like: %{sn}, %{connectionStatus} +You can use the following variables: %{sn}, %{connectionStatus} =item B<--unknown-operating-state> Set unknown threshold for status. -Can used special variables like: %{sn}, %{operatingState} +You can use the following variables: %{sn}, %{operatingState} =item B<--warning-operating-state> Set warning threshold for status. -Can used special variables like: %{sn}, %{operatingState} +You can use the following variables: %{sn}, %{operatingState} =item B<--critical-operating-state> Set critical threshold for status (Default: '%{operatingState} !~ /operating/i'). -Can used special variables like: %{sn}, %{operatingState} +You can use the following variables: %{sn}, %{operatingState} =item B<--unknown-autotest-state> Set unknown threshold for status. -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--warning-autotest-state> Set warning threshold for status. -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--critical-autotest-state> Set critical threshold for status (Default: '%{state} !~ /success/i'). -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--unknown-interface-status> Set unknown threshold for status. -Can used special variables like: %{sn}, %{name}, %{operatingStatus} +You can use the following variables: %{sn}, %{name}, %{operatingStatus} =item B<--warning-interface-status> Set warning threshold for status. -Can used special variables like: %{sn}, %{name}, %{operatingStatus} +You can use the following variables: %{sn}, %{name}, %{operatingStatus} =item B<--critical-interface-status> Set critical threshold for status (Default: '%{operatingStatus} !~ /up/i'). -Can used special variables like: %{sn}, %{name}, %{operatingStatus} +You can use the following variables: %{sn}, %{name}, %{operatingStatus} =item B<--unknown-vpn-ike-service-state> Set unknown threshold for status. -Can used special variables like: %{sn}, %{state} +You can use the following variables: %{sn}, %{state} =item B<--warning-vpn-ike-service-state> Set warning threshold for status. -Can used special variables like: %{sn}, %{state} +You can use the following variables: %{sn}, %{state} =item B<--critical-vpn-ike-service-state> Set critical threshold for status (Default: '%{state} =~ /stopped/i'). -Can used special variables like: %{sn}, %{state} +You can use the following variables: %{sn}, %{state} =item B<--unknown-vpn-ike-sa-state> Set unknown threshold for status. -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--warning-vpn-ike-sa-state> Set warning threshold for status. -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--critical-vpn-ike-sa-state> Set critical threshold for status (Default: '%{state} =~ /down/i'). -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--unknown-vpn-sa-state> Set unknown threshold for status. -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--warning-vpn-sa-state> Set warning threshold for status. -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--critical-vpn-sa-state> Set critical threshold for status (Default: '%{state} =~ /down/i'). -Can used special variables like: %{sn}, %{name}, %{state} +You can use the following variables: %{sn}, %{name}, %{state} =item B<--ntp-hostname> diff --git a/src/apps/thales/mistral/vs9/restapi/mode/mmccertificates.pm b/src/apps/thales/mistral/vs9/restapi/mode/mmccertificates.pm index c74a1d16e..ae1b25a58 100644 --- a/src/apps/thales/mistral/vs9/restapi/mode/mmccertificates.pm +++ b/src/apps/thales/mistral/vs9/restapi/mode/mmccertificates.pm @@ -229,17 +229,17 @@ Skip revoked certificates. =item B<--unknown-certificate-status> Set unknown threshold for status. -Can used special variables like: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName} +You can use the following variables: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName} =item B<--warning-certificate-status> Set warning threshold for status. -Can used special variables like: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName} +You can use the following variables: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName} =item B<--critical-certificate-status> Set critical threshold for status. -Can used special variables like: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName} +You can use the following variables: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/thales/mistral/vs9/restapi/mode/mmccluster.pm b/src/apps/thales/mistral/vs9/restapi/mode/mmccluster.pm index 928031960..ba58e35db 100644 --- a/src/apps/thales/mistral/vs9/restapi/mode/mmccluster.pm +++ b/src/apps/thales/mistral/vs9/restapi/mode/mmccluster.pm @@ -141,32 +141,32 @@ Check MMC cluster status. =item B<--unknown-cluster-status> Set unknown threshold for status (Default: '%{replicationStatus} =~ /unknown/i'). -Can used special variables like: %{enabled}, %{replicationStatus} +You can use the following variables: %{enabled}, %{replicationStatus} =item B<--warning-cluster-status> Set warning threshold for status (Default: '%{replicationStatus} =~ /not_synchronized/i'). -Can used special variables like: %{enabled}, %{replicationStatus} +You can use the following variables: %{enabled}, %{replicationStatus} =item B<--critical-cluster-status> Set critical threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-node-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-node-status> Set warning threshold for status (Default: '%{status} =~ /disconnected/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-node-status> Set critical threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/tomcat/web/mode/applications.pm b/src/apps/tomcat/web/mode/applications.pm index b55953d97..c73930244 100644 --- a/src/apps/tomcat/web/mode/applications.pm +++ b/src/apps/tomcat/web/mode/applications.pm @@ -206,17 +206,17 @@ Threshold critical for http response code =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} ne "running"'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} eq "stopped"'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/toshiba/storemate/sql/mode/maintenanceplan.pm b/src/apps/toshiba/storemate/sql/mode/maintenanceplan.pm index b1e7f0b3a..5d1d3dcd0 100644 --- a/src/apps/toshiba/storemate/sql/mode/maintenanceplan.pm +++ b/src/apps/toshiba/storemate/sql/mode/maintenanceplan.pm @@ -158,12 +158,12 @@ Database name (default: 'Framework'). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{description}, %{workstation_id}, %{since} +You can use the following variables: %{description}, %{workstation_id}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '1 == 1'. We match all errors). -Can used special variables like: %{description}, %{workstation_id}, %{since} +You can use the following variables: %{description}, %{workstation_id}, %{since} =item B<--timezone> diff --git a/src/apps/video/openheadend/snmp/mode/nodeusage.pm b/src/apps/video/openheadend/snmp/mode/nodeusage.pm index 3cdd527ff..74396fad9 100644 --- a/src/apps/video/openheadend/snmp/mode/nodeusage.pm +++ b/src/apps/video/openheadend/snmp/mode/nodeusage.pm @@ -169,12 +169,12 @@ Filter node name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{dep_status}, %{display} +You can use the following variables: %{dep_status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{dep_status} =~ /false/i'). -Can used special variables like: %{dep_status}, %{display} +You can use the following variables: %{dep_status}, %{display} =item B<--warning-*> diff --git a/src/apps/video/openheadend/snmp/mode/operationstatus.pm b/src/apps/video/openheadend/snmp/mode/operationstatus.pm index 3c948a3be..3b8490a86 100644 --- a/src/apps/video/openheadend/snmp/mode/operationstatus.pm +++ b/src/apps/video/openheadend/snmp/mode/operationstatus.pm @@ -166,12 +166,12 @@ Filter by operation type (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{dep_status}, %{display} +You can use the following variables: %{status}, %{dep_status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{dep_status} =~ /false/i'). -Can used special variables like: %{status}, %{dep_status}, %{display} +You can use the following variables: %{status}, %{dep_status}, %{display} =back diff --git a/src/apps/video/zixi/restapi/mode/broadcasterinputusage.pm b/src/apps/video/zixi/restapi/mode/broadcasterinputusage.pm index 4df2e9f01..74d2f75a2 100644 --- a/src/apps/video/zixi/restapi/mode/broadcasterinputusage.pm +++ b/src/apps/video/zixi/restapi/mode/broadcasterinputusage.pm @@ -191,12 +191,12 @@ Can be: 'traffic-in', 'traffic-out'. =item B<--warning-status> Set warning threshold for status (Default: -) -Can used special variables like: %{source}, %{status}, %{error}. +You can use the following variables: %{source}, %{status}, %{error}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i'). -Can used special variables like: %{source}, %{status}, %{error}. +You can use the following variables: %{source}, %{status}, %{error}. =back diff --git a/src/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm b/src/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm index 8d5ce37dc..7ff845ef0 100644 --- a/src/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm +++ b/src/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm @@ -256,12 +256,12 @@ Thresholds are on free license left. =item B<--warning-status> Set warning threshold for status (Default: -) -Can used special variables like: %{name}, %{error}, %{info}. +You can use the following variables: %{name}, %{error}, %{info}. =item B<--critical-status> Set critical threshold for status (Default: -). -Can used special variables like: %{name}, %{error}, %{info}. +You can use the following variables: %{name}, %{error}, %{info}. =back diff --git a/src/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm b/src/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm index ff997b8e2..420fae687 100644 --- a/src/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm +++ b/src/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm @@ -202,12 +202,12 @@ Can be: 'traffic-in', 'traffic-out', 'dropped-in'. =item B<--warning-status> Set warning threshold for status (Default: -) -Can used special variables like: %{name}, %{status}, %{error}. +You can use the following variables: %{name}, %{status}, %{error}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i'). -Can used special variables like: %{name}, %{status}, %{error}. +You can use the following variables: %{name}, %{status}, %{error}. =back diff --git a/src/apps/video/zixi/restapi/mode/feederinputusage.pm b/src/apps/video/zixi/restapi/mode/feederinputusage.pm index 6271340f1..6142ee311 100644 --- a/src/apps/video/zixi/restapi/mode/feederinputusage.pm +++ b/src/apps/video/zixi/restapi/mode/feederinputusage.pm @@ -162,12 +162,12 @@ Can be: 'traffic-in'. =item B<--warning-status> Set warning threshold for status (Default: -) -Can used special variables like: %{name}, %{active}, %{error}. +You can use the following variables: %{name}, %{active}, %{error}. =item B<--critical-status> Set critical threshold for status (Default: -). -Can used special variables like: %{name}, %{active}, %{error}. +You can use the following variables: %{name}, %{active}, %{error}. =back diff --git a/src/apps/video/zixi/restapi/mode/feederoutputusage.pm b/src/apps/video/zixi/restapi/mode/feederoutputusage.pm index 7d307dcf8..11be3515a 100644 --- a/src/apps/video/zixi/restapi/mode/feederoutputusage.pm +++ b/src/apps/video/zixi/restapi/mode/feederoutputusage.pm @@ -162,12 +162,12 @@ Can be: 'current-birate'. =item B<--warning-status> Set warning threshold for status (Default: -) -Can used special variables like: %{name}, %{active}, %{error}, %{con_stat}. +You can use the following variables: %{name}, %{active}, %{error}, %{con_stat}. =item B<--critical-status> Set critical threshold for status (Default: -). -Can used special variables like: %{name}, %{active}, %{error}, %{con_stat}. +You can use the following variables: %{name}, %{active}, %{error}, %{con_stat}. =back diff --git a/src/apps/virtualization/hpe/simplivity/restapi/mode/hosts.pm b/src/apps/virtualization/hpe/simplivity/restapi/mode/hosts.pm index 3da013d5e..68f9a94af 100644 --- a/src/apps/virtualization/hpe/simplivity/restapi/mode/hosts.pm +++ b/src/apps/virtualization/hpe/simplivity/restapi/mode/hosts.pm @@ -257,62 +257,62 @@ Filter hosts by name. =item B<--unknown-host-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-host-status> Set warning threshold for status (Default: '%{status} =~ /suspected/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-host-status> Set critical threshold for status (Default: '%{status} =~ /faulty/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-raid-status> Set unknown threshold for component status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-raid-status> Set warning threshold for component status (Default: '%{status} =~ /yellow/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-raid-status> Set critical threshold for component status (Default: '%{status} =~ /red/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-logical-drive-status> Set unknown threshold for component status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-logical-drive-status> Set warning threshold for component status (Default: '%{status} =~ /yellow/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-logical-drive-status> Set critical threshold for component status (Default: '%{status} =~ /red/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-physical-drive-status> Set unknown threshold for component status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-physical-drive-status> Set warning threshold for component status (Default: '%{status} =~ /yellow/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-physical-drive-status> Set critical threshold for component status (Default: '%{status} =~ /red/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/virtualization/hpe/simplivity/restapi/mode/virtualmachines.pm b/src/apps/virtualization/hpe/simplivity/restapi/mode/virtualmachines.pm index 122aed1cf..82a2c7402 100644 --- a/src/apps/virtualization/hpe/simplivity/restapi/mode/virtualmachines.pm +++ b/src/apps/virtualization/hpe/simplivity/restapi/mode/virtualmachines.pm @@ -173,17 +173,17 @@ Filter virtual machines by virtual machine name. =item B<--unknown-ha-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{ha_status}, %{vm_name} +You can use the following variables: %{ha_status}, %{vm_name} =item B<--warning-ha-status> Set warning threshold for status (Default: '%{status} =~ /degraded/'). -Can used special variables like: %{ha_status}, %{vm_name} +You can use the following variables: %{ha_status}, %{vm_name} =item B<--critical-ha-status> Set critical threshold for status. -Can used special variables like: %{ha_status}, %{vm_name} +You can use the following variables: %{ha_status}, %{vm_name} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/custom/connector.pm b/src/apps/vmware/connector/custom/connector.pm index 0767509a7..47ed76e69 100644 --- a/src/apps/vmware/connector/custom/connector.pm +++ b/src/apps/vmware/connector/custom/connector.pm @@ -333,17 +333,17 @@ Searchs are case insensitive. =item B<--unknown-connector-status> Set unknown threshold for connector status (Default: '%{code} < 0 || (%{code} > 0 && %{code} < 200)'). -Can used special variables like: %{code}, %{short_message}, %{extra_message}. +You can use the following variables: %{code}, %{short_message}, %{extra_message}. =item B<--warning-connector-status> Set warning threshold for connector status (Default: ''). -Can used special variables like: %{code}, %{short_message}, %{extra_message}. +You can use the following variables: %{code}, %{short_message}, %{extra_message}. =item B<--critical-connector-status> Set critical threshold for connector status (Default: ''). -Can used special variables like: %{code}, %{short_message}, %{extra_message}. +You can use the following variables: %{code}, %{short_message}, %{extra_message}. =back diff --git a/src/apps/vmware/connector/mode/alarmdatacenter.pm b/src/apps/vmware/connector/mode/alarmdatacenter.pm index 0548f406a..ab677e6e3 100644 --- a/src/apps/vmware/connector/mode/alarmdatacenter.pm +++ b/src/apps/vmware/connector/mode/alarmdatacenter.pm @@ -297,12 +297,12 @@ Check new alarms only. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /yellow/i). -Can used special variables like: %{status}, %{name}, %{entity}, %{type}. +You can use the following variables: %{status}, %{name}, %{entity}, %{type}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /red/i'). -Can used special variables like: %{status}, %{name}, %{entity}, %{type}. +You can use the following variables: %{status}, %{name}, %{entity}, %{type}. =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/alarmhost.pm b/src/apps/vmware/connector/mode/alarmhost.pm index 80da1dbe8..e7fe5c547 100644 --- a/src/apps/vmware/connector/mode/alarmhost.pm +++ b/src/apps/vmware/connector/mode/alarmhost.pm @@ -288,12 +288,12 @@ Check new alarms only. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /yellow/i). -Can used special variables like: %{status}, %{name}, %{entity}, %{type}. +You can use the following variables: %{status}, %{name}, %{entity}, %{type}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /red/i'). -Can used special variables like: %{status}, %{name}, %{entity}, %{type}. +You can use the following variables: %{status}, %{name}, %{entity}, %{type}. =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/countvmhost.pm b/src/apps/vmware/connector/mode/countvmhost.pm index f3ab006e8..4a9af9833 100644 --- a/src/apps/vmware/connector/mode/countvmhost.pm +++ b/src/apps/vmware/connector/mode/countvmhost.pm @@ -191,17 +191,17 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/cpuhost.pm b/src/apps/vmware/connector/mode/cpuhost.pm index 685160e1c..337c11699 100644 --- a/src/apps/vmware/connector/mode/cpuhost.pm +++ b/src/apps/vmware/connector/mode/cpuhost.pm @@ -197,17 +197,17 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/cpuvm.pm b/src/apps/vmware/connector/mode/cpuvm.pm index f3d9a9b5a..cc2009549 100644 --- a/src/apps/vmware/connector/mode/cpuvm.pm +++ b/src/apps/vmware/connector/mode/cpuvm.pm @@ -233,17 +233,17 @@ Search in following host(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/datastorecountvm.pm b/src/apps/vmware/connector/mode/datastorecountvm.pm index ee08ef0e2..89b81baf8 100644 --- a/src/apps/vmware/connector/mode/datastorecountvm.pm +++ b/src/apps/vmware/connector/mode/datastorecountvm.pm @@ -184,17 +184,17 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/datastorehost.pm b/src/apps/vmware/connector/mode/datastorehost.pm index 4c3802a46..7da8da310 100644 --- a/src/apps/vmware/connector/mode/datastorehost.pm +++ b/src/apps/vmware/connector/mode/datastorehost.pm @@ -189,17 +189,17 @@ Datastore name is a regexp. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/datastoreio.pm b/src/apps/vmware/connector/mode/datastoreio.pm index 2225cfb55..47ec07e1b 100644 --- a/src/apps/vmware/connector/mode/datastoreio.pm +++ b/src/apps/vmware/connector/mode/datastoreio.pm @@ -164,17 +164,17 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/datastoreiops.pm b/src/apps/vmware/connector/mode/datastoreiops.pm index 8634a9400..501e74bc9 100644 --- a/src/apps/vmware/connector/mode/datastoreiops.pm +++ b/src/apps/vmware/connector/mode/datastoreiops.pm @@ -242,17 +242,17 @@ Only display VMs with iops higher value (default: 50). =item B<--unknown-status> Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/mode/datastoresnapshot.pm b/src/apps/vmware/connector/mode/datastoresnapshot.pm index 0a61bc4b4..1e3d14e06 100644 --- a/src/apps/vmware/connector/mode/datastoresnapshot.pm +++ b/src/apps/vmware/connector/mode/datastoresnapshot.pm @@ -173,17 +173,17 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/datastoreusage.pm b/src/apps/vmware/connector/mode/datastoreusage.pm index e87e3da76..8bb9f857a 100644 --- a/src/apps/vmware/connector/mode/datastoreusage.pm +++ b/src/apps/vmware/connector/mode/datastoreusage.pm @@ -267,17 +267,17 @@ Explicitly ask vmware to refreshes free-space and capacity values (slower). =item B<--unknown-status> Set unknown threshold for status (Default: '%{accessible} !~ /^true|1$/i'). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{accessible} +You can use the following variables: %{accessible} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/mode/datastorevm.pm b/src/apps/vmware/connector/mode/datastorevm.pm index a817cda3b..224584297 100644 --- a/src/apps/vmware/connector/mode/datastorevm.pm +++ b/src/apps/vmware/connector/mode/datastorevm.pm @@ -243,17 +243,17 @@ Display virtual machine description. =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/mode/devicevm.pm b/src/apps/vmware/connector/mode/devicevm.pm index 49bae3e45..088c7816e 100644 --- a/src/apps/vmware/connector/mode/devicevm.pm +++ b/src/apps/vmware/connector/mode/devicevm.pm @@ -200,17 +200,17 @@ Device to check (Required) (Example: --device='VirtualCdrom'). =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i'). -Can used special variables like: %{connection_state} +You can use the following variables: %{connection_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state} +You can use the following variables: %{connection_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{connection_state} +You can use the following variables: %{connection_state} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/healthhost.pm b/src/apps/vmware/connector/mode/healthhost.pm index 48b50164f..f0831bc58 100644 --- a/src/apps/vmware/connector/mode/healthhost.pm +++ b/src/apps/vmware/connector/mode/healthhost.pm @@ -329,17 +329,17 @@ Check storage(s) status. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/mode/limitvm.pm b/src/apps/vmware/connector/mode/limitvm.pm index fbd50d3c3..48c49c335 100644 --- a/src/apps/vmware/connector/mode/limitvm.pm +++ b/src/apps/vmware/connector/mode/limitvm.pm @@ -242,32 +242,32 @@ Check disk limits (since vsphere 5.0). =item B<--warning-disk-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state}, %{limit} +You can use the following variables: %{connection_state}, %{power_state}, %{limit} =item B<--critical-disk-status> Set critical threshold for status (Default: '%{connection_state} !~ /^connected$/i || %{limit} != -1'). -Can used special variables like: %{connection_state}, %{power_state}, %{limit} +You can use the following variables: %{connection_state}, %{power_state}, %{limit} =item B<--warning-cpu-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state}, %{limit} +You can use the following variables: %{connection_state}, %{power_state}, %{limit} =item B<--critical-cpu-status> Set critical threshold for status (Default: '%{connection_state} !~ /^connected$/i || %{limit} != -1'). -Can used special variables like: %{connection_state}, %{power_state}, %{limit} +You can use the following variables: %{connection_state}, %{power_state}, %{limit} =item B<--warning-memory-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state}, %{limit} +You can use the following variables: %{connection_state}, %{power_state}, %{limit} =item B<--critical-memory-status> Set critical threshold for status (Default: '%{connection_state} !~ /^connected$/i || %{limit} != -1'). -Can used special variables like: %{connection_state}, %{power_state}, %{limit} +You can use the following variables: %{connection_state}, %{power_state}, %{limit} =back diff --git a/src/apps/vmware/connector/mode/maintenancehost.pm b/src/apps/vmware/connector/mode/maintenancehost.pm index 7c8dd4a53..4fd992339 100644 --- a/src/apps/vmware/connector/mode/maintenancehost.pm +++ b/src/apps/vmware/connector/mode/maintenancehost.pm @@ -145,27 +145,27 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-maintenance-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{maintenance} +You can use the following variables: %{maintenance} =item B<--critical-maintenance-status> Set critical threshold for status (Default: '%{maintenance} !~ /false/'). -Can used special variables like: %{maintenance} +You can use the following variables: %{maintenance} =back diff --git a/src/apps/vmware/connector/mode/memoryhost.pm b/src/apps/vmware/connector/mode/memoryhost.pm index 549379a22..58ed61bca 100644 --- a/src/apps/vmware/connector/mode/memoryhost.pm +++ b/src/apps/vmware/connector/mode/memoryhost.pm @@ -262,17 +262,17 @@ Thresholds are on free space left. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-consumed-memory> diff --git a/src/apps/vmware/connector/mode/memoryvm.pm b/src/apps/vmware/connector/mode/memoryvm.pm index cf9eef31b..8ebffb00c 100644 --- a/src/apps/vmware/connector/mode/memoryvm.pm +++ b/src/apps/vmware/connector/mode/memoryvm.pm @@ -340,17 +340,17 @@ Display virtual machine description. =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--units> diff --git a/src/apps/vmware/connector/mode/nethost.pm b/src/apps/vmware/connector/mode/nethost.pm index 3068f8711..09bb7a3dc 100644 --- a/src/apps/vmware/connector/mode/nethost.pm +++ b/src/apps/vmware/connector/mode/nethost.pm @@ -391,32 +391,32 @@ It monitors only ESX nic that belongs to the filtered vswitches. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-link-status> Set warning threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-link-status> Set warning threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--critical-link-status> Set critical threshold for status (Default: '%{link_status} !~ /up/'). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/mode/netvm.pm b/src/apps/vmware/connector/mode/netvm.pm index ec13c9d7a..e8e6b171b 100644 --- a/src/apps/vmware/connector/mode/netvm.pm +++ b/src/apps/vmware/connector/mode/netvm.pm @@ -323,17 +323,17 @@ Display virtual machine description. =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--speed-in> diff --git a/src/apps/vmware/connector/mode/servicehost.pm b/src/apps/vmware/connector/mode/servicehost.pm index 5da125bee..ed0c0db52 100644 --- a/src/apps/vmware/connector/mode/servicehost.pm +++ b/src/apps/vmware/connector/mode/servicehost.pm @@ -180,27 +180,27 @@ Filter services you want to check (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-service-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{running}, %{label}, %{policy} +You can use the following variables: %{running}, %{label}, %{policy} =item B<--critical-service-status> Set critical threshold for status (Default: '%{policy} =~ /^on|automatic/i && !%{running}'). -Can used special variables like: %{running}, %{label}, %{policy} +You can use the following variables: %{running}, %{label}, %{policy} =back diff --git a/src/apps/vmware/connector/mode/statuscluster.pm b/src/apps/vmware/connector/mode/statuscluster.pm index 4963760b3..c774f5ab3 100644 --- a/src/apps/vmware/connector/mode/statuscluster.pm +++ b/src/apps/vmware/connector/mode/statuscluster.pm @@ -132,17 +132,17 @@ Search in following datacenter(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{overall_status} =~ /gray/i || %{vsan_status} =~ /gray/i'). -Can used special variables like: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} +You can use the following variables: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} =item B<--warning-status> Set warning threshold for status (Default: '%{overall_status} =~ /yellow/i || %{vsan_status} =~ /yellow/i'). -Can used special variables like: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} +You can use the following variables: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} =item B<--critical-status> Set critical threshold for status (Default: '%{overall_status} =~ /red/i || %{vsan_status} =~ /red/i'). -Can used special variables like: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} +You can use the following variables: %{overall_status}, %{vsan_status}, %{drs_enabled}, %{ha_enabled} =back diff --git a/src/apps/vmware/connector/mode/statushost.pm b/src/apps/vmware/connector/mode/statushost.pm index fa51c18f1..ecd7c09bc 100644 --- a/src/apps/vmware/connector/mode/statushost.pm +++ b/src/apps/vmware/connector/mode/statushost.pm @@ -148,32 +148,32 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-overall-status> Set warning threshold for status (Default: '%{overall_status} =~ /gray/i'). -Can used special variables like: %{overall_status} +You can use the following variables: %{overall_status} =item B<--warning-overall-status> Set warning threshold for status (Default: '%{overall_status} =~ /yellow/i'). -Can used special variables like: %{overall_status} +You can use the following variables: %{overall_status} =item B<--critical-overall-status> Set critical threshold for status (Default: '%{overall_status} =~ /red/i'). -Can used special variables like: %{overall_status} +You can use the following variables: %{overall_status} =back diff --git a/src/apps/vmware/connector/mode/statusvm.pm b/src/apps/vmware/connector/mode/statusvm.pm index dc7cc0ae3..4a1bf2bee 100644 --- a/src/apps/vmware/connector/mode/statusvm.pm +++ b/src/apps/vmware/connector/mode/statusvm.pm @@ -168,32 +168,32 @@ Search in following host(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i'). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{connection_state} +You can use the following variables: %{connection_state} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--unknown-overall-status> Set unknown threshold for status (Default: '%{overall_status} =~ /gray/i'). -Can used special variables like: %{overall_status} +You can use the following variables: %{overall_status} =item B<--warning-overall-status> Set warning threshold for status (Default: '%{overall_status} =~ /yellow/i'). -Can used special variables like: %{overall_status} +You can use the following variables: %{overall_status} =item B<--critical-overall-status> Set critical threshold for status (Default: '%{overall_status} =~ /red/i'). -Can used special variables like: %{overall_status} +You can use the following variables: %{overall_status} =back diff --git a/src/apps/vmware/connector/mode/storagehost.pm b/src/apps/vmware/connector/mode/storagehost.pm index d419ea5a0..dc7b5787b 100644 --- a/src/apps/vmware/connector/mode/storagehost.pm +++ b/src/apps/vmware/connector/mode/storagehost.pm @@ -361,47 +361,47 @@ Filter paths by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i && %{maintenance} =~ /false/i'). -Can used special variables like: %{status}, %{maintenance} +You can use the following variables: %{status}, %{maintenance} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{maintenance} +You can use the following variables: %{status}, %{maintenance} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{maintenance} +You can use the following variables: %{status}, %{maintenance} =item B<--warning-adapter-status> Set warning threshold for adapter status. -Can used special variables like: %{name}, %{host}, %{status} +You can use the following variables: %{name}, %{host}, %{status} =item B<--critical-adapter-status> Set critical threshold for adapter status (Default: '%{status} =~ /fault/'). -Can used special variables like: %{name}, %{host}, %{status} +You can use the following variables: %{name}, %{host}, %{status} =item B<--warning-lun-status> Set warning threshold for lun status (Default: '%{status} =~ /degraded|quiesced/'). -Can used special variables like: %{name}, %{host}, %{status} +You can use the following variables: %{name}, %{host}, %{status} =item B<--critical-lun-status> Set critical threshold for lun status (Default: '%{status} =~ /lostcommunication|error/'). -Can used special variables like: %{name}, %{host}, %{status} +You can use the following variables: %{name}, %{host}, %{status} =item B<--warning-path-status> Set warning threshold for path status. -Can used special variables like: %{name}, %{host}, %{status} +You can use the following variables: %{name}, %{host}, %{status} =item B<--critical-path-status> Set critical threshold for path status (Default: '%{status} =~ /dead/'). -Can used special variables like: %{name}, %{host}, %{status} +You can use the following variables: %{name}, %{host}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/vmware/connector/mode/swaphost.pm b/src/apps/vmware/connector/mode/swaphost.pm index 365065789..8504c4415 100644 --- a/src/apps/vmware/connector/mode/swaphost.pm +++ b/src/apps/vmware/connector/mode/swaphost.pm @@ -151,17 +151,17 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/swapvm.pm b/src/apps/vmware/connector/mode/swapvm.pm index 00852aaa3..bbc8968a5 100644 --- a/src/apps/vmware/connector/mode/swapvm.pm +++ b/src/apps/vmware/connector/mode/swapvm.pm @@ -176,17 +176,17 @@ Display virtual machine description. =item B<--unknown-status> Set unknown threshold for status (Default: '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i'). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{connection_state}, %{power_state} +You can use the following variables: %{connection_state}, %{power_state} =item B<--warning-*> diff --git a/src/apps/vmware/connector/mode/timehost.pm b/src/apps/vmware/connector/mode/timehost.pm index 132319fca..435ac8f37 100644 --- a/src/apps/vmware/connector/mode/timehost.pm +++ b/src/apps/vmware/connector/mode/timehost.pm @@ -157,17 +157,17 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-time> diff --git a/src/apps/vmware/connector/mode/uptimehost.pm b/src/apps/vmware/connector/mode/uptimehost.pm index bcc011394..e8e1f0c6f 100644 --- a/src/apps/vmware/connector/mode/uptimehost.pm +++ b/src/apps/vmware/connector/mode/uptimehost.pm @@ -157,17 +157,17 @@ Search in following cluster(s) (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} !~ /^connected$/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-time> diff --git a/src/apps/vmware/vcsa/restapi/mode/health.pm b/src/apps/vmware/vcsa/restapi/mode/health.pm index 55a00e87a..bfa887a4e 100644 --- a/src/apps/vmware/vcsa/restapi/mode/health.pm +++ b/src/apps/vmware/vcsa/restapi/mode/health.pm @@ -121,17 +121,17 @@ Filter service (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{health}, %{display} +You can use the following variables: %{health}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{health}, %{display} +You can use the following variables: %{health}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{health} !~ /green/'). -Can used special variables like: %{health}, %{display} +You can use the following variables: %{health}, %{display} =back diff --git a/src/apps/vmware/vcsa/snmp/mode/interfaces.pm b/src/apps/vmware/vcsa/snmp/mode/interfaces.pm index a4f793a08..8b9f878d7 100644 --- a/src/apps/vmware/vcsa/snmp/mode/interfaces.pm +++ b/src/apps/vmware/vcsa/snmp/mode/interfaces.pm @@ -94,12 +94,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/voip/3cx/restapi/mode/extension.pm b/src/apps/voip/3cx/restapi/mode/extension.pm index 836967f51..5c6bfe6b9 100644 --- a/src/apps/voip/3cx/restapi/mode/extension.pm +++ b/src/apps/voip/3cx/restapi/mode/extension.pm @@ -165,17 +165,17 @@ Filter extension. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{extension}, %{registered}, %{dnd}, %{profile}, %{status}, %{duration} +You can use the following variables: %{extension}, %{registered}, %{dnd}, %{profile}, %{status}, %{duration} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{extension}, %{registered}, %{dnd}, %{profile}, %{status}, %{duration} +You can use the following variables: %{extension}, %{registered}, %{dnd}, %{profile}, %{status}, %{duration} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{extension}, %{registered}, %{dnd}, %{profile}, %{status}, %{duration} +You can use the following variables: %{extension}, %{registered}, %{dnd}, %{profile}, %{status}, %{duration} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/voip/3cx/restapi/mode/system.pm b/src/apps/voip/3cx/restapi/mode/system.pm index 7caf09967..11e4183a0 100644 --- a/src/apps/voip/3cx/restapi/mode/system.pm +++ b/src/apps/voip/3cx/restapi/mode/system.pm @@ -190,17 +190,17 @@ Filter updates' category. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{error}, %{service} +You can use the following variables: %{error}, %{service} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{error}, %{service} +You can use the following variables: %{error}, %{service} =item B<--critical-status> Set critical threshold for status (Default: '%{error} =~ /false/'). -Can used special variables like: %{error}, %{service} +You can use the following variables: %{error}, %{service} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/voip/asterisk/ami/mode/dahdistatus.pm b/src/apps/voip/asterisk/ami/mode/dahdistatus.pm index b58f9016a..7216ea204 100644 --- a/src/apps/voip/asterisk/ami/mode/dahdistatus.pm +++ b/src/apps/voip/asterisk/ami/mode/dahdistatus.pm @@ -126,12 +126,12 @@ Filter dahdi description (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /UNCONFIGURED|YEL|BLU/i'). -Can used special variables like: %{description}, %{status} +You can use the following variables: %{description}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /RED/i'). -Can used special variables like: %{description}, %{status} +You can use the following variables: %{description}, %{status} =back diff --git a/src/apps/voip/asterisk/ami/mode/sippeersusage.pm b/src/apps/voip/asterisk/ami/mode/sippeersusage.pm index 9b0cdc79e..f3e5f3d31 100644 --- a/src/apps/voip/asterisk/ami/mode/sippeersusage.pm +++ b/src/apps/voip/asterisk/ami/mode/sippeersusage.pm @@ -183,12 +183,12 @@ Filter sip peer name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /LAGGED|UNKNOWN/i'). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /UNREACHABLE/i'). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--warning-*> diff --git a/src/apps/vtom/restapi/mode/jobs.pm b/src/apps/vtom/restapi/mode/jobs.pm index e04bd93d9..492db6c0c 100644 --- a/src/apps/vtom/restapi/mode/jobs.pm +++ b/src/apps/vtom/restapi/mode/jobs.pm @@ -361,22 +361,22 @@ Can use format: 'Europe/London' or '+0100'. =item B<--warning-status> Set warning threshold for status (Default: -) -Can used special variables like: %{name}, %{status}, %{exit_code}, %{message}, %{environment}, %{application} +You can use the following variables: %{name}, %{status}, %{exit_code}, %{message}, %{environment}, %{application} =item B<--critical-status> Set critical threshold for status (Default: '%{exit_code} =~ /Error/i'). -Can used special variables like: %{name}, %{status}, %{exit_code}, %{message}, %{environment}, %{application} +You can use the following variables: %{name}, %{status}, %{exit_code}, %{message}, %{environment}, %{application} =item B<--warning-long> Set warning threshold for long jobs (Default: none) -Can used special variables like: %{name}, %{status}, %{elapsed}, %{application} +You can use the following variables: %{name}, %{status}, %{elapsed}, %{application} =item B<--critical-long> Set critical threshold for long jobs (Default: none). -Can used special variables like: %{name}, %{status}, %{elapsed}, %{application} +You can use the following variables: %{name}, %{status}, %{elapsed}, %{application} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/wallix/bastion/snmp/mode/license.pm b/src/apps/wallix/bastion/snmp/mode/license.pm index fe047e62e..d483251fe 100644 --- a/src/apps/wallix/bastion/snmp/mode/license.pm +++ b/src/apps/wallix/bastion/snmp/mode/license.pm @@ -303,12 +303,12 @@ Check license. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "expired"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unit> diff --git a/src/apps/wallix/bastion/snmp/mode/system.pm b/src/apps/wallix/bastion/snmp/mode/system.pm index efb0a9629..fceb4a3bc 100644 --- a/src/apps/wallix/bastion/snmp/mode/system.pm +++ b/src/apps/wallix/bastion/snmp/mode/system.pm @@ -169,12 +169,12 @@ Example: --filter-counters='status' =item B<--warning-services-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-services-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/wazuh/restapi/mode/agents.pm b/src/apps/wazuh/restapi/mode/agents.pm index c5616f4ae..05493a13a 100644 --- a/src/apps/wazuh/restapi/mode/agents.pm +++ b/src/apps/wazuh/restapi/mode/agents.pm @@ -148,12 +148,12 @@ Filter agent name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{node_name}, %{display} +You can use the following variables: %{status}, %{node_name}, %{display} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}, %{node_name}, %{display} +You can use the following variables: %{status}, %{node_name}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/apps/wazuh/restapi/mode/manager.pm b/src/apps/wazuh/restapi/mode/manager.pm index 9b2ba28bd..a655fd3a4 100644 --- a/src/apps/wazuh/restapi/mode/manager.pm +++ b/src/apps/wazuh/restapi/mode/manager.pm @@ -200,12 +200,12 @@ Filter log name (can be a regexp). =item B<--warning-process-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-process-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/airespace/snmp/mode/apstatus.pm b/src/centreon/common/airespace/snmp/mode/apstatus.pm index e33d12d17..fd263e09a 100644 --- a/src/centreon/common/airespace/snmp/mode/apstatus.pm +++ b/src/centreon/common/airespace/snmp/mode/apstatus.pm @@ -321,22 +321,22 @@ Monitor radio interfaces channels utilization. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "enable" and %{opstatus} !~ /associated|downloading/'). -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--warning-radio-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--critical-radio-status> Set critical threshold for status (Default: '%{admstatus} eq "enable" and %{opstatus} eq "down"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm b/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm index 3acd57864..940983872 100644 --- a/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm +++ b/src/centreon/common/bluearc/snmp/mode/clusterstatus.pm @@ -131,17 +131,17 @@ Filter node name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} =~ /unknown/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: -). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /offline/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =back diff --git a/src/centreon/common/bluearc/snmp/mode/interfaces.pm b/src/centreon/common/bluearc/snmp/mode/interfaces.pm index be68cc08a..7a2be78fd 100644 --- a/src/centreon/common/bluearc/snmp/mode/interfaces.pm +++ b/src/centreon/common/bluearc/snmp/mode/interfaces.pm @@ -94,12 +94,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/bluearc/snmp/mode/volumeusage.pm b/src/centreon/common/bluearc/snmp/mode/volumeusage.pm index 5457813d0..5ef8d67fb 100644 --- a/src/centreon/common/bluearc/snmp/mode/volumeusage.pm +++ b/src/centreon/common/bluearc/snmp/mode/volumeusage.pm @@ -221,12 +221,12 @@ Filter volume name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /needsChecking/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: -). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm b/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm index 4aa0a00e6..d88ba7da8 100644 --- a/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm +++ b/src/centreon/common/cisco/ironport/snmp/mode/mailusage.pm @@ -252,17 +252,17 @@ Check email security usage. =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{queue_status}, %{resource_conservation} +You can use the following variables: %{queue_status}, %{resource_conservation} =item B<--warning-status> Set warning threshold for status (Default: '%{resource_conservation} =~ /memoryShortage|queueSpaceShortage/i || %{queue_status} =~ /queueSpaceShortage/i'). -Can used special variables like: %{queue_status}, %{resource_conservation} +You can use the following variables: %{queue_status}, %{resource_conservation} =item B<--critical-status> Set critical threshold for status (Default: '%{resource_conservation} =~ /queueFull/i || %{queue_status} =~ /queueFull/i'). -Can used special variables like: %{queue_status}, %{resource_conservation} +You can use the following variables: %{queue_status}, %{resource_conservation} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm b/src/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm index 32ca790cd..1ac03ce3f 100644 --- a/src/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm +++ b/src/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm @@ -301,12 +301,12 @@ Threshold critical for http response code =item B<--warning-system-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{system_status} +You can use the following variables: %{system_status} =item B<--critical-system-status> Set critical threshold for status (Default: '%{system_status} !~ /online/i'). -Can used special variables like: %{system_status} +You can use the following variables: %{system_status} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/aaaservers.pm b/src/centreon/common/cisco/standard/snmp/mode/aaaservers.pm index ca43d7e20..74e2ef782 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/aaaservers.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/aaaservers.pm @@ -304,17 +304,17 @@ Filter AAA server by name (E.g.: 10.199.126.100:1812:1813. Format: [address]:[au =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /dead/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/bgp.pm b/src/centreon/common/cisco/standard/snmp/mode/bgp.pm index 54020811e..1db282dc7 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/bgp.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/bgp.pm @@ -264,17 +264,17 @@ Filter based on IP of peers (regexp allowed) =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{adminStatus}, %{state}, %{localAddr}, %{remoteAddr}, %{remoteAs} +You can use the following variables: %{adminStatus}, %{state}, %{localAddr}, %{remoteAddr}, %{remoteAs} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{adminStatus}, %{state}, %{localAddr}, %{remoteAddr}, %{remoteAs} +You can use the following variables: %{adminStatus}, %{state}, %{localAddr}, %{remoteAddr}, %{remoteAs} =item B<--critical-status> Set critical threshold for status (Default: '%{adminStatus} =~ /start/ && %{state} !~ /established/'). -Can used special variables like: %{adminStatus}, %{state}, %{localAddr}, %{remoteAddr}, %{remoteAs} +You can use the following variables: %{adminStatus}, %{state}, %{localAddr}, %{remoteAddr}, %{remoteAs} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/configuration.pm b/src/centreon/common/cisco/standard/snmp/mode/configuration.pm index 1357861a9..90ace34b6 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/configuration.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/configuration.pm @@ -132,12 +132,12 @@ Check Cisco changed and saved configurations (CISCO-CONFIG-MAN-MIB). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{running_last_changed}, %{running_last_saved}, %{startup_last_changed} +You can use the following variables: %{running_last_changed}, %{running_last_saved}, %{startup_last_changed} =item B<--critical-status> Set critical threshold for status (Default: '%{running_last_changed} > %{running_last_saved}'). -Can used special variables like: %{running_last_changed}, %{running_last_saved}, %{startup_last_changed} +You can use the following variables: %{running_last_changed}, %{running_last_saved}, %{startup_last_changed} =back diff --git a/src/centreon/common/cisco/standard/snmp/mode/interfaces.pm b/src/centreon/common/cisco/standard/snmp/mode/interfaces.pm index 8400d824e..a834d4b50 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/interfaces.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/interfaces.pm @@ -244,12 +244,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/memoryflash.pm b/src/centreon/common/cisco/standard/snmp/mode/memoryflash.pm index 8f699ce76..e3b600558 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/memoryflash.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/memoryflash.pm @@ -195,17 +195,17 @@ Check memory flash usages. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /readOnly/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/qosusage.pm b/src/centreon/common/cisco/standard/snmp/mode/qosusage.pm index c251f8584..dddcb4df3 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/qosusage.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/qosusage.pm @@ -431,7 +431,7 @@ sub manage_selection { (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); if (scalar(keys %{$self->{interface_classmap}}) <= 0 && !defined($options{disco})) { - $self->{output}->add_option_msg(short_msg => 'Cannot found classmap.'); + $self->{output}->add_option_msg(short_msg => 'Cannot find classmap.'); $self->{output}->option_exit(); } } diff --git a/src/centreon/common/cisco/standard/snmp/mode/stack.pm b/src/centreon/common/cisco/standard/snmp/mode/stack.pm index 145f2c0da..8de08f172 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/stack.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/stack.pm @@ -280,22 +280,22 @@ Set thresholds on members count for each states. =item B<--warning-stack-status> Set warning threshold for stack status (Default: ''). -Can used special variables like: %{stack_status} +You can use the following variables: %{stack_status} =item B<--critical-stack-status> Set critical threshold for stack status (Default: '%{stack_status} =~ /notredundant/'). -Can used special variables like: %{stack_status} +You can use the following variables: %{stack_status} =item B<--warning-status> Set warning threshold for members status (Default: ''). -Can used special variables like: %{name}, %{role}, %{state} +You can use the following variables: %{name}, %{role}, %{state} =item B<--critical-status> Set critical threshold for member status (Default: '%{state} !~ /ready/ && %{state} !~ /provisioned/'). -Can used special variables like: %{name}, %{role}, %{state} +You can use the following variables: %{name}, %{role}, %{state} Role can be: 'master', 'member', 'notMember', 'standby'. diff --git a/src/centreon/common/cisco/standard/snmp/mode/vpc.pm b/src/centreon/common/cisco/standard/snmp/mode/vpc.pm index dd430d4b8..a28ce8fc1 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/vpc.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/vpc.pm @@ -345,47 +345,47 @@ Check virtual port-channel (vPC). =item B<--unknown-peer-status> Set unknown threshold for status. -Can used special variables like: %{role}, %{role_last}, %{domain_id} +You can use the following variables: %{role}, %{role_last}, %{domain_id} =item B<--warning-peer-status> Set warning threshold for status. -Can used special variables like: %{role}, %{role_last}, %{domain_id} +You can use the following variables: %{role}, %{role_last}, %{domain_id} =item B<--critical-peer-status> Set critical threshold for status (Default: '%{role} ne %{role_last}'). -Can used special variables like: %{role}, %{role_last}, %{domain_id} +You can use the following variables: %{role}, %{role_last}, %{domain_id} =item B<--unknown-keepalive-status> Set unknown threshold for status. -Can used special variables like: %{keepalive_status}, %{domain_id} +You can use the following variables: %{keepalive_status}, %{domain_id} =item B<--warning-keepalive-status> Set warning threshold for status. -Can used special variables like: %{keepalive_status}, %{domain_id} +You can use the following variables: %{keepalive_status}, %{domain_id} =item B<--critical-keepalive-status> Set critical threshold for status (Default: '%{keepalive_status} ne "alive"'). -Can used special variables like: %{keepalive_status}, %{domain_id} +You can use the following variables: %{keepalive_status}, %{domain_id} =item B<--unknown-link-status> Set unknown threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-link-status> Set warning threshold for status (Default: '%{link_status} =~ /downStar/i') -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--critical-link-status> Set critical threshold for status (Default: '%{link_status} eq "down"'). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/vss.pm b/src/centreon/common/cisco/standard/snmp/mode/vss.pm index b5ce2c041..60c2e7d60 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/vss.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/vss.pm @@ -267,47 +267,47 @@ Check virtual switching system. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{mode} +You can use the following variables: %{mode} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{mode} +You can use the following variables: %{mode} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{mode} +You can use the following variables: %{mode} =item B<--unknown-member-status> Set unknown threshold for status. -Can used special variables like: %{role}, %{role_last}, %{switch_id} +You can use the following variables: %{role}, %{role_last}, %{switch_id} =item B<--warning-member-status> Set warning threshold for status. -Can used special variables like: %{role}, %{role_last}, %{switch_id} +You can use the following variables: %{role}, %{role_last}, %{switch_id} =item B<--critical-member-status> Set critical threshold for status (Default: '%{role} ne %{role_last}'). -Can used special variables like: %{role}, %{role_last}, %{switch_id} +You can use the following variables: %{role}, %{role_last}, %{switch_id} =item B<--unknown-link-status> Set unknown threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-link-status> Set warning threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--critical-link-status> Set critical threshold for status (Default: '%{link_status} eq "down"'). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cisco/standard/snmp/mode/wan3g.pm b/src/centreon/common/cisco/standard/snmp/mode/wan3g.pm index b6ffa65e4..b979af3e2 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/wan3g.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/wan3g.pm @@ -359,77 +359,77 @@ Filter by name (can be a regexp). =item B<--unknown-modem-status> Set unknown threshold for status (Default: '%{modem_status} =~ /unknown/i'). -Can used special variables like: %{modem_status}, %{display} +You can use the following variables: %{modem_status}, %{display} =item B<--warning-modem-status> Set warning threshold for status (Default: '%{modem_status} =~ /lowPowerMode/i'). -Can used special variables like: %{modem_status}, %{display} +You can use the following variables: %{modem_status}, %{display} =item B<--critical-modem-status> Set critical threshold for status (Default: '%{modem_status} =~ /offLine/i'). -Can used special variables like: %{modem_status}, %{display} +You can use the following variables: %{modem_status}, %{display} =item B<--unknown-connection-status> Set unknown threshold for status (Default: '%{connection_status} =~ /unknown/i'). -Can used special variables like: %{connection_status}, %{display} +You can use the following variables: %{connection_status}, %{display} =item B<--warning-connection-status> Set warning threshold for status. -Can used special variables like: %{connection_status}, %{display} +You can use the following variables: %{connection_status}, %{display} =item B<--critical-connection-status> Set critical threshold for status (Default: '%{connection_status} =~ /inactive|idle|disconnected|error/i'). -Can used special variables like: %{connection_status}, %{display} +You can use the following variables: %{connection_status}, %{display} =item B<--unknown-sim-status> Set unknown threshold for status (Default: '%{sim_status} =~ /unknown/i'). -Can used special variables like: %{sim_status}, %{display} +You can use the following variables: %{sim_status}, %{display} =item B<--warning-sim-status> Set warning threshold for status. -Can used special variables like: %{sim_status}, %{display} +You can use the following variables: %{sim_status}, %{display} =item B<--critical-sim-status> Set critical threshold for status (Default: '%{sim_status} !~ /ok|unknown/i'). -Can used special variables like: %{sim_status}, %{display} +You can use the following variables: %{sim_status}, %{display} =item B<--unknown-radio-status> Set unknown threshold for status (Default: '%{current_band} =~ /unknown/i'). -Can used special variables like: %{current_band}, %{channel_number}, %{display} +You can use the following variables: %{current_band}, %{channel_number}, %{display} =item B<--warning-radio-status> Set warning threshold for status. -Can used special variables like: %{current_band}, %{channel_number}, %{display} +You can use the following variables: %{current_band}, %{channel_number}, %{display} =item B<--critical-radio-status> Set critical threshold for status (Default: '%{current_band} =~ /invalid|none/i'). -Can used special variables like: %{current_band}, %{channel_number}, %{display} +You can use the following variables: %{current_band}, %{channel_number}, %{display} =item B<--unknown-network-status> Set unknown threshold for status (Default: '%{service_status} =~ /unknown/i'). -Can used special variables like: %{service_status}, %{display} +You can use the following variables: %{service_status}, %{display} =item B<--warning-network-status> Set warning threshold for status. -Can used special variables like: %{service_status}, %{display} +You can use the following variables: %{service_status}, %{display} =item B<--critical-network-status> Set critical threshold for status (Default: '%{service_status} =~ /emergencyOnly|noService/i'). -Can used special variables like: %{service_status}, %{display} +You can use the following variables: %{service_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm b/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm index 832586cd1..969f6a2c2 100644 --- a/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm +++ b/src/centreon/common/cps/ups/snmp/mode/batterystatus.pm @@ -144,17 +144,17 @@ Check battery status and charge remaining. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown|notPresent/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /low/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cps/ups/snmp/mode/inputlines.pm b/src/centreon/common/cps/ups/snmp/mode/inputlines.pm index d47985305..0526ad6bb 100644 --- a/src/centreon/common/cps/ups/snmp/mode/inputlines.pm +++ b/src/centreon/common/cps/ups/snmp/mode/inputlines.pm @@ -132,17 +132,17 @@ Check INPUT lines metrics. =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /normal/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/cps/ups/snmp/mode/outputlines.pm b/src/centreon/common/cps/ups/snmp/mode/outputlines.pm index efd27c2d9..972a69966 100644 --- a/src/centreon/common/cps/ups/snmp/mode/outputlines.pm +++ b/src/centreon/common/cps/ups/snmp/mode/outputlines.pm @@ -166,17 +166,17 @@ Check output lines metrics. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /rebooting|onBattery|onBypass/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/emc/navisphere/mode/hbastate.pm b/src/centreon/common/emc/navisphere/mode/hbastate.pm index b07eb85b2..d1772567a 100644 --- a/src/centreon/common/emc/navisphere/mode/hbastate.pm +++ b/src/centreon/common/emc/navisphere/mode/hbastate.pm @@ -182,9 +182,9 @@ Set hba uid to check (not set, means 'all'). =item B<--path-status> -Set how much path must be connected (Can be multiple). +Set how many paths must be connected (can be defined multiple times). Syntax: [WARNING],[CRITICAL],filter_uid,filter_server -Example: ,@0:1,.*,.* - Means all server must have at least two paths connected. +Example: ,@0:1,.*,.* - Means all servers must have at least two paths connected. =back diff --git a/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm b/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm index 9be386ab9..1d253cfd8 100644 --- a/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm +++ b/src/centreon/common/fortinet/fortigate/snmp/mode/apusage.pm @@ -239,17 +239,17 @@ Filter by access point name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admin} eq "enable" and %{status} !~ /online/i''). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =back diff --git a/src/centreon/common/fortinet/fortigate/snmp/mode/clusterstatus.pm b/src/centreon/common/fortinet/fortigate/snmp/mode/clusterstatus.pm index 1e48a6324..eacd6f2d7 100644 --- a/src/centreon/common/fortinet/fortigate/snmp/mode/clusterstatus.pm +++ b/src/centreon/common/fortinet/fortigate/snmp/mode/clusterstatus.pm @@ -271,12 +271,12 @@ Check cluster status. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{serial}, %{hostname}, %{sync_status}, %{role}, %{roleLast} +You can use the following variables: %{serial}, %{hostname}, %{sync_status}, %{role}, %{roleLast} =item B<--critical-status> Set critical threshold for status (Default: '%{role} ne %{roleLast} or %{sync_status} =~ /unsynchronized/'). -Can used special variables like: %{serial}, %{hostname}, %{sync_status}, %{role}, %{roleLast} +You can use the following variables: %{serial}, %{hostname}, %{sync_status}, %{role}, %{roleLast} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/fortinet/fortigate/snmp/mode/interfaces.pm b/src/centreon/common/fortinet/fortigate/snmp/mode/interfaces.pm index 8280974a3..087548ec7 100644 --- a/src/centreon/common/fortinet/fortigate/snmp/mode/interfaces.pm +++ b/src/centreon/common/fortinet/fortigate/snmp/mode/interfaces.pm @@ -105,12 +105,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/fortinet/fortigate/snmp/mode/sdwan.pm b/src/centreon/common/fortinet/fortigate/snmp/mode/sdwan.pm index 0e842c970..3798222c4 100644 --- a/src/centreon/common/fortinet/fortigate/snmp/mode/sdwan.pm +++ b/src/centreon/common/fortinet/fortigate/snmp/mode/sdwan.pm @@ -365,17 +365,17 @@ Filter sd-wan links by vdom name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{vdom}, %{id}, %{name}, %{ifName} +You can use the following variables: %{state}, %{vdom}, %{id}, %{name}, %{ifName} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{vdom}, %{id}, %{name}, %{ifName} +You can use the following variables: %{state}, %{vdom}, %{id}, %{name}, %{ifName} =item B<--critical-status> Set critical threshold for status (Default: '%{state} eq "down"'). -Can used special variables like: %{state}, %{vdom}, %{id}, %{name}, %{ifName} +You can use the following variables: %{state}, %{vdom}, %{id}, %{name}, %{ifName} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/fortinet/fortigate/snmp/mode/vdomusage.pm b/src/centreon/common/fortinet/fortigate/snmp/mode/vdomusage.pm index a58c3bdc8..cb72b7ebf 100644 --- a/src/centreon/common/fortinet/fortigate/snmp/mode/vdomusage.pm +++ b/src/centreon/common/fortinet/fortigate/snmp/mode/vdomusage.pm @@ -436,12 +436,12 @@ Time in minutes before reloading cache file (default: 60). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{op_mode}, %{ha_state} +You can use the following variables: %{op_mode}, %{ha_state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{op_mode}, %{ha_state} +You can use the following variables: %{op_mode}, %{ha_state} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/h3c/snmp/mode/interfaces.pm b/src/centreon/common/h3c/snmp/mode/interfaces.pm index 990c615b0..7b3427770 100644 --- a/src/centreon/common/h3c/snmp/mode/interfaces.pm +++ b/src/centreon/common/h3c/snmp/mode/interfaces.pm @@ -226,12 +226,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/riverbed/steelhead/snmp/mode/status.pm b/src/centreon/common/riverbed/steelhead/snmp/mode/status.pm index 188c46965..3c0a1f78e 100644 --- a/src/centreon/common/riverbed/steelhead/snmp/mode/status.pm +++ b/src/centreon/common/riverbed/steelhead/snmp/mode/status.pm @@ -149,12 +149,12 @@ Check the current status of the optimization service. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{health}, %{status} +You can use the following variables: %{health}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{health} !~ /Healthy/ || %{status} !~ /running/'). -Can used special variables like: %{health}, %{status} +You can use the following variables: %{health}, %{status} =item B<--warning-uptime> diff --git a/src/centreon/common/xppc/snmp/mode/batterystatus.pm b/src/centreon/common/xppc/snmp/mode/batterystatus.pm index 89d4c4cff..1f70006ad 100644 --- a/src/centreon/common/xppc/snmp/mode/batterystatus.pm +++ b/src/centreon/common/xppc/snmp/mode/batterystatus.pm @@ -146,17 +146,17 @@ Example: --filter-counters='status|current' =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /low/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/common/xppc/snmp/mode/outputlines.pm b/src/centreon/common/xppc/snmp/mode/outputlines.pm index 2578277ff..9b0eb4b20 100644 --- a/src/centreon/common/xppc/snmp/mode/outputlines.pm +++ b/src/centreon/common/xppc/snmp/mode/outputlines.pm @@ -140,17 +140,17 @@ Check output lines metrics. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /rebooting|onBypass/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /onBattery/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-*> B<--critical-*> diff --git a/src/centreon/plugins/http.pm b/src/centreon/plugins/http.pm index 261dc066e..12ce5ba75 100644 --- a/src/centreon/plugins/http.pm +++ b/src/centreon/plugins/http.pm @@ -252,7 +252,7 @@ HTTP abstraction layer for lwp and curl backends =item B<--http-peer-addr> -Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) +Set the address you want to connect to. Useful if hostname is only a vhost, to avoid IP resolution. =item B<--proxyurl> @@ -260,7 +260,7 @@ Proxy URL =item B<--proxypac> -Proxy pac file (can be an url or local file) +Proxy pac file (can be a URL or local file) =item B<--insecure> diff --git a/src/centreon/plugins/output.pm b/src/centreon/plugins/output.pm index 6e9c5efb4..b2ff3dca3 100644 --- a/src/centreon/plugins/output.pm +++ b/src/centreon/plugins/output.pm @@ -1516,26 +1516,33 @@ Output class =item B<--verbose> -Display long output. +Display extended status information (long output). =item B<--debug> -Display also debug messages. +Display debug messages. =item B<--filter-perfdata> Filter perfdata that match the regexp. +Eg: adding --filter-perfdata='avg' will remove all metrics that do not contain +'avg' from performance data. =item B<--filter-perfdata-adv> -Advanced perfdata filter. - -Eg: --filter-perfdata-adv='not (%(value) == 0 and %(max) eq "")' +Filter perfdata based on a "if" condition using the following variables: +label, value, unit, warning, critical, min, max. +Variables must be written either %{variable} or %(variable). +Eg: adding --filter-perfdata-adv='not (%(value) == 0 and %(max) eq "")' will +remove all metrics whose value equals 0 and that don't have a maximum value. =item B<--explode-perfdata-max> -Put max perfdata (if it exist) in a specific perfdata -(without values: same with '_max' suffix) (Multiple options) +Create a new metric for each metric that comes with a maximum limit. The new +metric will be named identically with a '_max' suffix). +Eg: it will split 'used_prct'=26.93%;0:80;0:90;0;100 +into 'used_prct'=26.93%;0:80;0:90;0;100 'used_prct_max'=100%;;;; + =item B<--change-perfdata> B<--extend-perfdata> @@ -1575,11 +1582,16 @@ Sum traffic by interface: --extend-perfdata-group='traffic_in_(.*),traffic_$1,su =item B<--change-short-output> B<--change-long-output> -Change short/long output display: --change-short-output=pattern~replace~modifier +Modify the short/long output that is returned by the plugin. +Syntax: --change-short-output=pattern~replacement~modifier +Most commonly used modifiers are i (case insensitive) and g (replace all occurrences). +Eg: adding --change-short-output='OK~Up~gi' will replace all occurrences of 'OK', 'ok', 'Ok' or 'oK' with 'Up' =item B<--change-exit> -Change exit code: --change-exit=unknown=critical +Replace an exit code with one of your choice. +Eg: adding --change-exit=unknown=critical will result in a CRITICAL state +instead of an UNKNOWN state. =item B<--range-perfdata> @@ -1588,21 +1600,22 @@ Change perfdata range thresholds display: =item B<--filter-uom> -Filter UOM that match the regexp. +Masks the units when they don't match the given regular expression. =item B<--opt-exit> -Optional exit code for an execution error (i.e. wrong option provided, -SSH connection refused, timeout, etc) -(Default: unknown). +Replace the exit code in case of an execution error (i.e. wrong option provided, +SSH connection refused, timeout, etc). Default: unknown. =item B<--output-ignore-perfdata> -Remove perfdata from output. +Remove all the metrics from the service. The service will still have a status +and an output. =item B<--output-ignore-label> -Remove label status from output. +Remove the status label from the beginning of the output. +Eg: 'OK: Ram Total:...' will become 'Ram Total:...' =item B<--output-xml> @@ -1630,11 +1643,11 @@ Display discovery values (if the mode manages it). =item B<--float-precision> -Set the float precision for thresholds (Default: 8). +Set the float precision for thresholds (default: 8). =item B<--source-encoding> -Set encoding of monitoring sources (In some case. Default: 'UTF-8'). +Set encoding of monitoring sources (in some cases. Default: 'UTF-8'). =head1 DESCRIPTION diff --git a/src/centreon/plugins/script.pm b/src/centreon/plugins/script.pm index 529286aa6..a81711581 100644 --- a/src/centreon/plugins/script.pm +++ b/src/centreon/plugins/script.pm @@ -451,7 +451,7 @@ Specify the path to the plugin. =item B<--list-plugin> -Print available plugins. +List all available plugins. =item B<--version> @@ -475,7 +475,8 @@ Set script timeout. =item B<--environment> -Set environment variables for the script (prefer to set it before running it for better performance). +Set environment variables for the script (set them in the execution environment +before running it for better performance). =item B<--convert-args> diff --git a/src/centreon/plugins/script_custom.pm b/src/centreon/plugins/script_custom.pm index fc38d6177..60221f453 100644 --- a/src/centreon/plugins/script_custom.pm +++ b/src/centreon/plugins/script_custom.pm @@ -271,15 +271,15 @@ __END__ =item B<--mode> -Choose a mode. +Define the mode in which you want the plugin to be executed (see --list-mode). =item B<--dyn-mode> -Specify a mode with the path (separated by '::'). +Specify a mode with the module's path (advanced). =item B<--list-mode> -List available modes. +List all available modes. =item B<--mode-version> @@ -287,23 +287,25 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display plugin version. +Display the plugin's version. =item B<--custommode> -Choose a custom mode. +When a plugin offers several ways (CLI, library, etc.) to get the an information +the desired one must be defined with this option. =item B<--list-custommode> -List available custom modes. +List all available custom modes. =item B<--multiple> -Multiple custom mode objects (required by some specific modes) +Multiple custom mode objects. This may be required by some specific modes (advanced). =item B<--pass-manager> -Use a password manager. +Define the password manager you want to use. +Supported managers are: environment, file, keepass, hashicorpvault and teampass. =back diff --git a/src/centreon/plugins/script_simple.pm b/src/centreon/plugins/script_simple.pm index a090b4b01..e66b4743b 100644 --- a/src/centreon/plugins/script_simple.pm +++ b/src/centreon/plugins/script_simple.pm @@ -202,15 +202,15 @@ __END__ =item B<--mode> -Choose a mode. +Define the mode in which you want the plugin to be executed (see --list-mode). =item B<--dyn-mode> -Specify a mode with the path (separated by '::'). +Specify a mode with the module's path (advanced). =item B<--list-mode> -List available modes. +List all available modes. =item B<--mode-version> @@ -218,11 +218,12 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display plugin version. +Display the plugin's version. =item B<--pass-manager> -Use a password manager. +Define the password manager you want to use. +Supported managers are: environment, file, keepass, hashicorpvault and teampass. =back diff --git a/src/centreon/plugins/script_snmp.pm b/src/centreon/plugins/script_snmp.pm index d85d4a524..c8c9c1af3 100644 --- a/src/centreon/plugins/script_snmp.pm +++ b/src/centreon/plugins/script_snmp.pm @@ -210,15 +210,15 @@ __END__ =item B<--mode> -Choose a mode. +Define the mode in which you want the plugin to be executed (see --list-mode). =item B<--dyn-mode> -Specify a mode with the path (separated by '::'). +Specify a mode with the module's path (advanced). =item B<--list-mode> -List available modes. +List all available modes. =item B<--mode-version> @@ -226,11 +226,12 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display plugin version. +Display the plugin's version. =item B<--pass-manager> -Use a password manager. +Define the password manager you want to use. +Supported managers are: environment, file, keepass, hashicorpvault and teampass. =back diff --git a/src/centreon/plugins/script_sql.pm b/src/centreon/plugins/script_sql.pm index 639e68462..d7b786ee6 100644 --- a/src/centreon/plugins/script_sql.pm +++ b/src/centreon/plugins/script_sql.pm @@ -270,15 +270,15 @@ __END__ =item B<--mode> -Choose a mode. +Define the mode in which you want the plugin to be executed (see --list-mode). =item B<--dyn-mode> -Specify a mode with the path (separated by '::'). +Specify a mode with the module's path (advanced). =item B<--list-mode> -List available modes. +List all available modes. =item B<--mode-version> @@ -286,7 +286,7 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display plugin version. +Display the plugin's version. =item B<--sqlmode> @@ -302,7 +302,8 @@ Multiple database connections (required by some specific modes). =item B<--pass-manager> -Use a password manager. +Define the password manager you want to use. +Supported managers are: environment, file, keepass, hashicorpvault and teampass. =back diff --git a/src/centreon/plugins/script_wsman.pm b/src/centreon/plugins/script_wsman.pm index a094723cf..2ad465462 100644 --- a/src/centreon/plugins/script_wsman.pm +++ b/src/centreon/plugins/script_wsman.pm @@ -206,15 +206,15 @@ __END__ =item B<--mode> -Choose a mode. +Define the mode in which you want the plugin to be executed (see --list-mode). =item B<--dyn-mode> -Specify a mode with the path (separated by '::'). +Specify a mode with the module's path (advanced). =item B<--list-mode> -List available modes. +List all available modes. =item B<--mode-version> @@ -222,11 +222,12 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display plugin version. +Display the plugin's version. =item B<--pass-manager> -Use a password manager. +Define the password manager you want to use. +Supported managers are: environment, file, keepass, hashicorpvault and teampass. =back diff --git a/src/centreon/plugins/statefile.pm b/src/centreon/plugins/statefile.pm index 0cf02546b..a6b8ba2bc 100644 --- a/src/centreon/plugins/statefile.pm +++ b/src/centreon/plugins/statefile.pm @@ -459,7 +459,7 @@ Memcached server to use (only one server). =item B<--redis-server> -Redis server to use (only one server). SYntax: address[:port] +Redis server to use (only one server). Syntax: address[:port] =item B<--redis-attribute> diff --git a/src/cloud/aws/apigateway/mode/latency.pm b/src/cloud/aws/apigateway/mode/latency.pm index bb2381e3f..94495bb1e 100644 --- a/src/cloud/aws/apigateway/mode/latency.pm +++ b/src/cloud/aws/apigateway/mode/latency.pm @@ -181,7 +181,7 @@ Default statistic: 'sum' =item B<--api-name> -Set the API name (Required) (Can be multiple). +Set the API name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/apigateway/mode/requests.pm b/src/cloud/aws/apigateway/mode/requests.pm index 1c17bc89b..0a28163ad 100644 --- a/src/cloud/aws/apigateway/mode/requests.pm +++ b/src/cloud/aws/apigateway/mode/requests.pm @@ -182,7 +182,7 @@ Default statistic: 'sum' =item B<--api-name> -Set the api name (Required) (Can be multiple). +Set the api name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/billing/mode/estimatedcharges.pm b/src/cloud/aws/billing/mode/estimatedcharges.pm index 355ee80c5..57615ceb8 100644 --- a/src/cloud/aws/billing/mode/estimatedcharges.pm +++ b/src/cloud/aws/billing/mode/estimatedcharges.pm @@ -127,7 +127,7 @@ See 'https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/billing-metr =item B<--service> -Set the Amazon service (Required) (Can be multiple). +Set the Amazon service (Required) (can be defined multiple times). =item B<--warning-billing> diff --git a/src/cloud/aws/cloudfront/mode/errors.pm b/src/cloud/aws/cloudfront/mode/errors.pm index b8381af59..6f32fe4af 100644 --- a/src/cloud/aws/cloudfront/mode/errors.pm +++ b/src/cloud/aws/cloudfront/mode/errors.pm @@ -158,7 +158,7 @@ Default statistic: 'average' / Valid statistic: 'average'. =item B<--id> -Set the instance id (Required) (Can be multiple). +Set the instance id (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/cloudfront/mode/requests.pm b/src/cloud/aws/cloudfront/mode/requests.pm index 101c493e0..2b52a321d 100644 --- a/src/cloud/aws/cloudfront/mode/requests.pm +++ b/src/cloud/aws/cloudfront/mode/requests.pm @@ -154,7 +154,7 @@ Default statistic: 'sum' / Valid statistic: 'sum'. =item B<--id> -Set the instance id (Required) (Can be multiple). +Set the instance id (Required) (can be defined multiple times). =item B<--warning-requests> diff --git a/src/cloud/aws/cloudfront/mode/throughput.pm b/src/cloud/aws/cloudfront/mode/throughput.pm index 628e58708..5cb878a70 100644 --- a/src/cloud/aws/cloudfront/mode/throughput.pm +++ b/src/cloud/aws/cloudfront/mode/throughput.pm @@ -163,7 +163,7 @@ Default statistic: 'sum' / Valid statistic: 'sum'. =item B<--id> -Set the instance id (Required) (Can be multiple). +Set the instance id (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/cloudwatch/mode/getalarms.pm b/src/cloud/aws/cloudwatch/mode/getalarms.pm index b72cd2f5d..af5ee4af8 100644 --- a/src/cloud/aws/cloudwatch/mode/getalarms.pm +++ b/src/cloud/aws/cloudwatch/mode/getalarms.pm @@ -164,12 +164,12 @@ Filter by alarm name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{state_value} =~ /INSUFFICIENT_DATA/i') -Can used special variables like: %{alarm_name}, %{state_value}, %{metric_name}, %{last_update} +You can use the following variables: %{alarm_name}, %{state_value}, %{metric_name}, %{last_update} =item B<--critical-status> Set critical threshold for status (Default: '%{state_value} =~ /ALARM/i'). -Can used special variables like: %{alarm_name}, %{state_value}, %{metric_name}, %{last_update} +You can use the following variables: %{alarm_name}, %{state_value}, %{metric_name}, %{last_update} =item B<--memory> diff --git a/src/cloud/aws/cloudwatchlogs/mode/getlogs.pm b/src/cloud/aws/cloudwatchlogs/mode/getlogs.pm index c53b28ffe..e9b69a1b0 100644 --- a/src/cloud/aws/cloudwatchlogs/mode/getlogs.pm +++ b/src/cloud/aws/cloudwatchlogs/mode/getlogs.pm @@ -175,17 +175,17 @@ If not set: lookup logs since the last execution. =item B<--unknown-status> Set unknown threshold for status (Default: '') -Can used special variables like: %{message}, %{stream_name}, %{since} +You can use the following variables: %{message}, %{stream_name}, %{since} =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{message}, %{stream_name}, %{since} +You can use the following variables: %{message}, %{stream_name}, %{since} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{message}, %{stream_name}, %{since} +You can use the following variables: %{message}, %{stream_name}, %{since} =back diff --git a/src/cloud/aws/custom/awscli.pm b/src/cloud/aws/custom/awscli.pm index 00559678e..385938762 100644 --- a/src/cloud/aws/custom/awscli.pm +++ b/src/cloud/aws/custom/awscli.pm @@ -1032,7 +1032,7 @@ Set cloudwatch statistics (Can be: 'minimum', 'maximum', 'average', 'sum'). =item B<--zeroed> -Set metrics value to 0 if none. Usefull when CloudWatch +Set metrics value to 0 if none. Useful when CloudWatch does not return value when not defined. =item B<--timeout> diff --git a/src/cloud/aws/custom/paws.pm b/src/cloud/aws/custom/paws.pm index c9fe895a8..dc6b433c6 100644 --- a/src/cloud/aws/custom/paws.pm +++ b/src/cloud/aws/custom/paws.pm @@ -890,7 +890,7 @@ Set cloudwatch statistics =item B<--zeroed> -Set metrics value to 0 if none. Usefull when CloudWatch +Set metrics value to 0 if none. Useful when CloudWatch does not return value when not defined. =item B<--proxyurl> diff --git a/src/cloud/aws/directconnect/mode/connections.pm b/src/cloud/aws/directconnect/mode/connections.pm index f11d23263..992581d71 100644 --- a/src/cloud/aws/directconnect/mode/connections.pm +++ b/src/cloud/aws/directconnect/mode/connections.pm @@ -230,12 +230,12 @@ Filter metrics (Can be: 'ConnectionBpsEgress', 'ConnectionBpsIngress', =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{bandwidth}, %{connectionName} +You can use the following variables: %{state}, %{bandwidth}, %{connectionName} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{bandwidth}, %{connectionName} +You can use the following variables: %{state}, %{bandwidth}, %{connectionName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/aws/directconnect/mode/virtualinterfaces.pm b/src/cloud/aws/directconnect/mode/virtualinterfaces.pm index e616440c8..b7e0ef6d0 100644 --- a/src/cloud/aws/directconnect/mode/virtualinterfaces.pm +++ b/src/cloud/aws/directconnect/mode/virtualinterfaces.pm @@ -227,12 +227,12 @@ Filter metrics (Can be: 'VirtualInterfaceBpsEgress', 'VirtualInterfaceBpsIngress =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{vlan}, %{type}, %{virtualInterfaceId} +You can use the following variables: %{state}, %{vlan}, %{type}, %{virtualInterfaceId} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{vlan}, %{type}, %{virtualInterfaceId} +You can use the following variables: %{state}, %{vlan}, %{type}, %{virtualInterfaceId} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/aws/ec2/mode/cpu.pm b/src/cloud/aws/ec2/mode/cpu.pm index 909a05fb6..46d037b63 100644 --- a/src/cloud/aws/ec2/mode/cpu.pm +++ b/src/cloud/aws/ec2/mode/cpu.pm @@ -196,7 +196,7 @@ Set the instance type (Required) (Can be: 'asg', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/ec2/mode/diskio.pm b/src/cloud/aws/ec2/mode/diskio.pm index 793db8466..6f9a4062d 100644 --- a/src/cloud/aws/ec2/mode/diskio.pm +++ b/src/cloud/aws/ec2/mode/diskio.pm @@ -237,7 +237,7 @@ Set the instance type (Required) (Can be: 'asg', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--add-ebs-metrics> diff --git a/src/cloud/aws/ec2/mode/instancesstatus.pm b/src/cloud/aws/ec2/mode/instancesstatus.pm index d92413d97..3fb5f85fb 100644 --- a/src/cloud/aws/ec2/mode/instancesstatus.pm +++ b/src/cloud/aws/ec2/mode/instancesstatus.pm @@ -279,12 +279,12 @@ Select the unit for uptime threshold. May be 's' for seconds, 'm' for minutes, =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/aws/ec2/mode/network.pm b/src/cloud/aws/ec2/mode/network.pm index aafd32850..ee333032d 100644 --- a/src/cloud/aws/ec2/mode/network.pm +++ b/src/cloud/aws/ec2/mode/network.pm @@ -191,7 +191,7 @@ Set the instance type (Required) (Can be: 'asg', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/ec2/mode/status.pm b/src/cloud/aws/ec2/mode/status.pm index fcbf4e15b..6faa40b3f 100644 --- a/src/cloud/aws/ec2/mode/status.pm +++ b/src/cloud/aws/ec2/mode/status.pm @@ -196,18 +196,18 @@ Set the instance type (Required) (Can be: 'asg', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}. +You can use the following variables: %{status}. 'status' can be: 'passed', 'failed'. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. 'status' can be: 'passed', 'failed'. =back diff --git a/src/cloud/aws/efs/mode/connections.pm b/src/cloud/aws/efs/mode/connections.pm index 3ab667e11..351d7b36f 100644 --- a/src/cloud/aws/efs/mode/connections.pm +++ b/src/cloud/aws/efs/mode/connections.pm @@ -139,7 +139,7 @@ See 'https://docs.aws.amazon.com/efs/latest/ug/monitoring-cloudwatch.html' for m =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--warning-client-connections> diff --git a/src/cloud/aws/efs/mode/datausage.pm b/src/cloud/aws/efs/mode/datausage.pm index bd98eb2ac..9739acc0b 100644 --- a/src/cloud/aws/efs/mode/datausage.pm +++ b/src/cloud/aws/efs/mode/datausage.pm @@ -172,7 +172,7 @@ See 'https://docs.aws.amazon.com/efs/latest/ug/monitoring-cloudwatch.html' for m =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/elasticache/mode/commandsmemcached.pm b/src/cloud/aws/elasticache/mode/commandsmemcached.pm index a0c477a15..1a3dd3a27 100644 --- a/src/cloud/aws/elasticache/mode/commandsmemcached.pm +++ b/src/cloud/aws/elasticache/mode/commandsmemcached.pm @@ -215,7 +215,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/commandsredis.pm b/src/cloud/aws/elasticache/mode/commandsredis.pm index 441d9364f..5fb325a12 100644 --- a/src/cloud/aws/elasticache/mode/commandsredis.pm +++ b/src/cloud/aws/elasticache/mode/commandsredis.pm @@ -217,7 +217,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/connections.pm b/src/cloud/aws/elasticache/mode/connections.pm index 3ada8f825..29e982b41 100644 --- a/src/cloud/aws/elasticache/mode/connections.pm +++ b/src/cloud/aws/elasticache/mode/connections.pm @@ -228,7 +228,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/cpu.pm b/src/cloud/aws/elasticache/mode/cpu.pm index 4624b184e..c26bdd5b7 100644 --- a/src/cloud/aws/elasticache/mode/cpu.pm +++ b/src/cloud/aws/elasticache/mode/cpu.pm @@ -161,7 +161,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/evictions.pm b/src/cloud/aws/elasticache/mode/evictions.pm index a07b36f29..52169f39c 100644 --- a/src/cloud/aws/elasticache/mode/evictions.pm +++ b/src/cloud/aws/elasticache/mode/evictions.pm @@ -216,7 +216,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/items.pm b/src/cloud/aws/elasticache/mode/items.pm index 261521ea1..1ee4bae8f 100644 --- a/src/cloud/aws/elasticache/mode/items.pm +++ b/src/cloud/aws/elasticache/mode/items.pm @@ -228,7 +228,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/network.pm b/src/cloud/aws/elasticache/mode/network.pm index 3589d95ea..fa2451630 100644 --- a/src/cloud/aws/elasticache/mode/network.pm +++ b/src/cloud/aws/elasticache/mode/network.pm @@ -218,7 +218,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/replication.pm b/src/cloud/aws/elasticache/mode/replication.pm index 8ec210c91..4cec454e0 100644 --- a/src/cloud/aws/elasticache/mode/replication.pm +++ b/src/cloud/aws/elasticache/mode/replication.pm @@ -233,7 +233,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/requestsmemcached.pm b/src/cloud/aws/elasticache/mode/requestsmemcached.pm index f9fe5a300..030cdc7c4 100644 --- a/src/cloud/aws/elasticache/mode/requestsmemcached.pm +++ b/src/cloud/aws/elasticache/mode/requestsmemcached.pm @@ -216,7 +216,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/requestsredis.pm b/src/cloud/aws/elasticache/mode/requestsredis.pm index 4545b5f14..eeb4f2e20 100644 --- a/src/cloud/aws/elasticache/mode/requestsredis.pm +++ b/src/cloud/aws/elasticache/mode/requestsredis.pm @@ -214,7 +214,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/usagememcached.pm b/src/cloud/aws/elasticache/mode/usagememcached.pm index 586960f3f..e8172be66 100644 --- a/src/cloud/aws/elasticache/mode/usagememcached.pm +++ b/src/cloud/aws/elasticache/mode/usagememcached.pm @@ -167,7 +167,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elasticache/mode/usageredis.pm b/src/cloud/aws/elasticache/mode/usageredis.pm index c0ae8767f..ca305aeb3 100644 --- a/src/cloud/aws/elasticache/mode/usageredis.pm +++ b/src/cloud/aws/elasticache/mode/usageredis.pm @@ -167,7 +167,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the cluster name (Required) (Can be multiple). +Set the cluster name (Required) (can be defined multiple times). =item B<--node-id> diff --git a/src/cloud/aws/elb/application/mode/connections.pm b/src/cloud/aws/elb/application/mode/connections.pm index 280c0c00f..488806b9d 100644 --- a/src/cloud/aws/elb/application/mode/connections.pm +++ b/src/cloud/aws/elb/application/mode/connections.pm @@ -211,13 +211,13 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::application::plugin --customm See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html' for more informations. -Default statistic: 'sum' / Most usefull statistics: 'sum'. +Default statistic: 'sum' / Most useful statistics: 'sum'. =over 8 =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/application/mode/httpcodes.pm b/src/cloud/aws/elb/application/mode/httpcodes.pm index 33cee5688..e7bc15568 100644 --- a/src/cloud/aws/elb/application/mode/httpcodes.pm +++ b/src/cloud/aws/elb/application/mode/httpcodes.pm @@ -225,13 +225,13 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::application::plugin --customm See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html' for more informations. -Default statistic: 'sum' / Most usefull statistics: 'sum'. +Default statistic: 'sum' / Most useful statistics: 'sum'. =over 8 =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/application/mode/targetshealth.pm b/src/cloud/aws/elb/application/mode/targetshealth.pm index 6c738bd65..f8554dfdd 100644 --- a/src/cloud/aws/elb/application/mode/targetshealth.pm +++ b/src/cloud/aws/elb/application/mode/targetshealth.pm @@ -205,13 +205,13 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::application::plugin --customm See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html' for more informations. -Default statistic: 'average' / Most usefull statistics: 'average', 'minimum', 'maximum'. +Default statistic: 'average' / Most useful statistics: 'average', 'minimum', 'maximum'. =over 8 =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/classic/mode/httpcodes.pm b/src/cloud/aws/elb/classic/mode/httpcodes.pm index 5c407ce08..769688a6b 100644 --- a/src/cloud/aws/elb/classic/mode/httpcodes.pm +++ b/src/cloud/aws/elb/classic/mode/httpcodes.pm @@ -241,7 +241,7 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode= See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. -Default statistic: 'sum' / Most usefull statistics: 'sum'. +Default statistic: 'sum' / Most useful statistics: 'sum'. =over 8 @@ -251,7 +251,7 @@ Set the instance type (Required) (Can be: 'loadbalancer', 'availabilityzone'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/classic/mode/performances.pm b/src/cloud/aws/elb/classic/mode/performances.pm index cb31708cc..84b42b09a 100644 --- a/src/cloud/aws/elb/classic/mode/performances.pm +++ b/src/cloud/aws/elb/classic/mode/performances.pm @@ -216,7 +216,7 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode= See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. -Default statistic: 'sum', 'average' / Most usefull statistics: RequestCount: 'sum', Latency: 'average'. +Default statistic: 'sum', 'average' / Most useful statistics: RequestCount: 'sum', Latency: 'average'. =over 8 @@ -226,7 +226,7 @@ Set the instance type (Required) (Can be: 'loadbalancer', 'availabilityzone'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/classic/mode/queues.pm b/src/cloud/aws/elb/classic/mode/queues.pm index 4b96b058d..da61418ee 100644 --- a/src/cloud/aws/elb/classic/mode/queues.pm +++ b/src/cloud/aws/elb/classic/mode/queues.pm @@ -217,7 +217,7 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode= See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. -Default statistic: 'sum', 'maximum' / Most usefull statistics: SpilloverCount: 'sum', SurgeQueueLength: 'maximum'. +Default statistic: 'sum', 'maximum' / Most useful statistics: SpilloverCount: 'sum', SurgeQueueLength: 'maximum'. =over 8 @@ -227,7 +227,7 @@ Set the instance type (Required) (Can be: 'loadbalancer', 'availabilityzone'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/classic/mode/targetshealth.pm b/src/cloud/aws/elb/classic/mode/targetshealth.pm index 40acc6e81..f3eb6f87f 100644 --- a/src/cloud/aws/elb/classic/mode/targetshealth.pm +++ b/src/cloud/aws/elb/classic/mode/targetshealth.pm @@ -217,7 +217,7 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode= See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. -Default statistic: 'average' / Most usefull statistics: 'average', 'minimum', 'maximum'. +Default statistic: 'average' / Most useful statistics: 'average', 'minimum', 'maximum'. =over 8 @@ -227,7 +227,7 @@ Set the instance type (Required) (Can be: 'loadbalancer', 'availabilityzone'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/elb/network/mode/targetshealth.pm b/src/cloud/aws/elb/network/mode/targetshealth.pm index b572ed353..3e55d7243 100644 --- a/src/cloud/aws/elb/network/mode/targetshealth.pm +++ b/src/cloud/aws/elb/network/mode/targetshealth.pm @@ -201,13 +201,13 @@ perl centreon_plugins.pl --plugin=cloud::aws::elb::network::plugin --custommode= See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-cloudwatch-metrics.html' for more informations. -Default statistic: 'average' / Most usefull statistics: 'average', 'minimum', 'maximum'. +Default statistic: 'average' / Most useful statistics: 'average', 'minimum', 'maximum'. =over 8 =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--availability-zone> diff --git a/src/cloud/aws/fsx/mode/datausage.pm b/src/cloud/aws/fsx/mode/datausage.pm index a7ed176a1..ec5561e8a 100644 --- a/src/cloud/aws/fsx/mode/datausage.pm +++ b/src/cloud/aws/fsx/mode/datausage.pm @@ -171,7 +171,7 @@ See 'https://docs.aws.amazon.com/efs/latest/ug/efs-metrics.html' for more inform =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/fsx/mode/freespace.pm b/src/cloud/aws/fsx/mode/freespace.pm index a9a8872e3..77f2c565a 100644 --- a/src/cloud/aws/fsx/mode/freespace.pm +++ b/src/cloud/aws/fsx/mode/freespace.pm @@ -131,7 +131,7 @@ See 'https://docs.aws.amazon.com/efs/latest/ug/efs-metrics.html' for more inform =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--statistic> diff --git a/src/cloud/aws/kinesis/mode/recordsstats.pm b/src/cloud/aws/kinesis/mode/recordsstats.pm index 3f4b2b900..527fdbbeb 100644 --- a/src/cloud/aws/kinesis/mode/recordsstats.pm +++ b/src/cloud/aws/kinesis/mode/recordsstats.pm @@ -221,7 +221,7 @@ Check metrics about records statistics in Kinesis streams. =item B<--name> -Set the stream name (Required) (Can be multiple). +Set the stream name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/kinesis/mode/streams.pm b/src/cloud/aws/kinesis/mode/streams.pm index 9ebc43548..7cfc0cd11 100644 --- a/src/cloud/aws/kinesis/mode/streams.pm +++ b/src/cloud/aws/kinesis/mode/streams.pm @@ -198,7 +198,7 @@ note: Outgoing* metrics are only available when enhanced stats are enabled (paid =item B<--stream-name> -Set the stream name (Required) (Can be multiple). +Set the stream name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/lambda/mode/invocations.pm b/src/cloud/aws/lambda/mode/invocations.pm index b71e7d06b..30c62ff03 100644 --- a/src/cloud/aws/lambda/mode/invocations.pm +++ b/src/cloud/aws/lambda/mode/invocations.pm @@ -206,7 +206,7 @@ Default statistic: 'sum', 'average'. =item B<--name> -Set the function name (Required) (Can be multiple). +Set the function name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/connections.pm b/src/cloud/aws/rds/mode/connections.pm index 97a775151..284a62c0d 100644 --- a/src/cloud/aws/rds/mode/connections.pm +++ b/src/cloud/aws/rds/mode/connections.pm @@ -179,7 +179,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/cpu.pm b/src/cloud/aws/rds/mode/cpu.pm index ad9e0c74c..04aafcafe 100644 --- a/src/cloud/aws/rds/mode/cpu.pm +++ b/src/cloud/aws/rds/mode/cpu.pm @@ -191,7 +191,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/diskio.pm b/src/cloud/aws/rds/mode/diskio.pm index b17a7a889..58a7ad358 100644 --- a/src/cloud/aws/rds/mode/diskio.pm +++ b/src/cloud/aws/rds/mode/diskio.pm @@ -217,7 +217,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/instancestatus.pm b/src/cloud/aws/rds/mode/instancestatus.pm index 68cf4659c..6e69bb98f 100644 --- a/src/cloud/aws/rds/mode/instancestatus.pm +++ b/src/cloud/aws/rds/mode/instancestatus.pm @@ -196,12 +196,12 @@ Filter by instance id (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> diff --git a/src/cloud/aws/rds/mode/network.pm b/src/cloud/aws/rds/mode/network.pm index fae464a34..86ad76d47 100644 --- a/src/cloud/aws/rds/mode/network.pm +++ b/src/cloud/aws/rds/mode/network.pm @@ -179,7 +179,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/queries.pm b/src/cloud/aws/rds/mode/queries.pm index 6dce2f2ef..98be95b92 100644 --- a/src/cloud/aws/rds/mode/queries.pm +++ b/src/cloud/aws/rds/mode/queries.pm @@ -193,7 +193,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/storage.pm b/src/cloud/aws/rds/mode/storage.pm index bc4df4c24..48c1dc9c1 100644 --- a/src/cloud/aws/rds/mode/storage.pm +++ b/src/cloud/aws/rds/mode/storage.pm @@ -345,7 +345,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/transactions.pm b/src/cloud/aws/rds/mode/transactions.pm index d4827672a..43edc7e71 100644 --- a/src/cloud/aws/rds/mode/transactions.pm +++ b/src/cloud/aws/rds/mode/transactions.pm @@ -191,7 +191,7 @@ Set the instance type (Required) (Can be: 'cluster', 'instance'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/rds/mode/volume.pm b/src/cloud/aws/rds/mode/volume.pm index 7770e5533..9b7f2544c 100644 --- a/src/cloud/aws/rds/mode/volume.pm +++ b/src/cloud/aws/rds/mode/volume.pm @@ -241,7 +241,7 @@ Set the instance type (Required) (Can be: 'cluster'). =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/s3/mode/bucketsize.pm b/src/cloud/aws/s3/mode/bucketsize.pm index b12aa93bc..119772f03 100644 --- a/src/cloud/aws/s3/mode/bucketsize.pm +++ b/src/cloud/aws/s3/mode/bucketsize.pm @@ -172,12 +172,12 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--storage-type> Set the storage type of the bucket (Default: 'StandardStorage') -(Can be multiple: 'StandardStorage', 'StandardIAStorage', 'ReducedRedundancyStorage'). +((can be defined multiple times): 'StandardStorage', 'StandardIAStorage', 'ReducedRedundancyStorage'). =item B<--warning-$metric$-$storagetype$-$statistic$> diff --git a/src/cloud/aws/s3/mode/objects.pm b/src/cloud/aws/s3/mode/objects.pm index 79ebd2a20..d90c8c562 100644 --- a/src/cloud/aws/s3/mode/objects.pm +++ b/src/cloud/aws/s3/mode/objects.pm @@ -155,7 +155,7 @@ Default statistic: 'average' / All satistics are valid. =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--warning-$metric$-$statistic$> diff --git a/src/cloud/aws/s3/mode/requests.pm b/src/cloud/aws/s3/mode/requests.pm index 5d892e63a..2aa901f27 100644 --- a/src/cloud/aws/s3/mode/requests.pm +++ b/src/cloud/aws/s3/mode/requests.pm @@ -147,7 +147,7 @@ Default statistic: 'sum' / Valid statistics: 'sum'. =item B<--name> -Set the instance name (Required) (Can be multiple). +Set the instance name (Required) (can be defined multiple times). =item B<--filter-metric> diff --git a/src/cloud/aws/ses/mode/emails.pm b/src/cloud/aws/ses/mode/emails.pm index 3ce6cc990..6bb7d6eea 100644 --- a/src/cloud/aws/ses/mode/emails.pm +++ b/src/cloud/aws/ses/mode/emails.pm @@ -229,7 +229,7 @@ See 'https://docs.aws.amazon.com/ses/latest/DeveloperGuide/monitor-sending-activ =item B<--dimension> -Set SES dimensions (Can be multiple). Syntax: +Set SES dimensions (can be defined multiple times). Syntax: --dimension='DimensionName1=Value1' --dimension='DimensionName2=Value2'. =item B<--warning-emails-*> diff --git a/src/cloud/azure/analytics/eventhubs/mode/health.pm b/src/cloud/azure/analytics/eventhubs/mode/health.pm index 913f9a795..ed152061c 100644 --- a/src/cloud/azure/analytics/eventhubs/mode/health.pm +++ b/src/cloud/azure/analytics/eventhubs/mode/health.pm @@ -54,22 +54,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/common/storageaccount/health.pm b/src/cloud/azure/common/storageaccount/health.pm index d7a14f184..854224b15 100644 --- a/src/cloud/azure/common/storageaccount/health.pm +++ b/src/cloud/azure/common/storageaccount/health.pm @@ -54,7 +54,7 @@ __END__ Check Storage Account health status. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -74,22 +74,22 @@ Default: 'Microsoft.Storage'. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/compute/aks/mode/health.pm b/src/cloud/azure/compute/aks/mode/health.pm index 1b193616d..8c8c2918f 100644 --- a/src/cloud/azure/compute/aks/mode/health.pm +++ b/src/cloud/azure/compute/aks/mode/health.pm @@ -40,7 +40,7 @@ __END__ =head1 MODE Check Azure Kubernetes Cluster health status. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -56,25 +56,25 @@ Set resource group (Required if resource's name is used). Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/compute/virtualmachine/mode/health.pm b/src/cloud/azure/compute/virtualmachine/mode/health.pm index 8156348bf..300e26465 100644 --- a/src/cloud/azure/compute/virtualmachine/mode/health.pm +++ b/src/cloud/azure/compute/virtualmachine/mode/health.pm @@ -41,7 +41,7 @@ __END__ Check Virtual Machine health status. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/compute/vmscalesets/mode/health.pm b/src/cloud/azure/compute/vmscalesets/mode/health.pm index a2dfb2605..3f2faa29a 100644 --- a/src/cloud/azure/compute/vmscalesets/mode/health.pm +++ b/src/cloud/azure/compute/vmscalesets/mode/health.pm @@ -40,7 +40,7 @@ __END__ =head1 MODE Check Azure Virtual Machine Scale Sets Health. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -56,25 +56,25 @@ Set resource group (Required if resource's name is used). Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/custom/api.pm b/src/cloud/azure/custom/api.pm index c40569e82..328a70e63 100644 --- a/src/cloud/azure/custom/api.pm +++ b/src/cloud/azure/custom/api.pm @@ -1255,13 +1255,13 @@ Microsoft Azure Rest API To connect to the Azure Rest API, you must register an application. -Follow the 'How-to guide' in https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal +Follow the 'How-to guide' at https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal The application needs the 'Monitoring Reader' role (See https://docs.microsoft.com/en-us/azure/azure-monitor/platform/roles-permissions-security#monitoring-reader). This custom mode is using the 'OAuth 2.0 Client Credentials Grant Flow' -For futher informations, visit https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow +For further informations, visit https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow =over 8 @@ -1299,12 +1299,14 @@ Set interval of the metric query (Can be : PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total', 'count'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--zeroed> -Set metrics value to 0 if none. Usefull when Monitor -does not return value when not defined. +Set metrics value to 0 if they are missing. Useful when some metrics are +undefined. =item B<--timeout> diff --git a/src/cloud/azure/custom/azcli.pm b/src/cloud/azure/custom/azcli.pm index 3ca8bc9da..494c3e8fb 100644 --- a/src/cloud/azure/custom/azcli.pm +++ b/src/cloud/azure/custom/azcli.pm @@ -646,12 +646,14 @@ Set interval of the metric query (Can be : PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total', 'count'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--zeroed> -Set metrics value to 0 if none. Usefull when Monitor -does not return value when not defined. +Set metrics value to 0 if they are missing. Useful when some metrics are +undefined. =item B<--timeout> diff --git a/src/cloud/azure/database/cosmosdb/mode/health.pm b/src/cloud/azure/database/cosmosdb/mode/health.pm index 9c5e53f5f..dc5513d8a 100644 --- a/src/cloud/azure/database/cosmosdb/mode/health.pm +++ b/src/cloud/azure/database/cosmosdb/mode/health.pm @@ -54,22 +54,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/database/redis/mode/health.pm b/src/cloud/azure/database/redis/mode/health.pm index ee9f85dff..7efb5b970 100644 --- a/src/cloud/azure/database/redis/mode/health.pm +++ b/src/cloud/azure/database/redis/mode/health.pm @@ -54,22 +54,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/database/sqldatabase/mode/health.pm b/src/cloud/azure/database/sqldatabase/mode/health.pm index eac17463e..51c386f81 100644 --- a/src/cloud/azure/database/sqldatabase/mode/health.pm +++ b/src/cloud/azure/database/sqldatabase/mode/health.pm @@ -56,25 +56,25 @@ Set resource group (Required if resource's name is used). Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/database/sqlserver/mode/serverstatus.pm b/src/cloud/azure/database/sqlserver/mode/serverstatus.pm index 88cd08f2b..42c357ccc 100644 --- a/src/cloud/azure/database/sqlserver/mode/serverstatus.pm +++ b/src/cloud/azure/database/sqlserver/mode/serverstatus.pm @@ -127,12 +127,12 @@ Filter server name (Can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{fqdn}, %{display} +You can use the following variables: %{state}, %{fqdn}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "Ready"'). -Can used special variables like: %{state}, %{fqdn}, %{display} +You can use the following variables: %{state}, %{fqdn}, %{display} =back diff --git a/src/cloud/azure/integration/eventgrid/mode/health.pm b/src/cloud/azure/integration/eventgrid/mode/health.pm index 2e1e8f6f7..9fab26528 100644 --- a/src/cloud/azure/integration/eventgrid/mode/health.pm +++ b/src/cloud/azure/integration/eventgrid/mode/health.pm @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/integration/servicebus/mode/health.pm b/src/cloud/azure/integration/servicebus/mode/health.pm index ec1685d72..1591d3e6c 100644 --- a/src/cloud/azure/integration/servicebus/mode/health.pm +++ b/src/cloud/azure/integration/servicebus/mode/health.pm @@ -41,7 +41,7 @@ __END__ Check Service Bus namespace status. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/management/monitor/mode/getmetrics.pm b/src/cloud/azure/management/monitor/mode/getmetrics.pm index 987f563dd..f58b574ce 100644 --- a/src/cloud/azure/management/monitor/mode/getmetrics.pm +++ b/src/cloud/azure/management/monitor/mode/getmetrics.pm @@ -233,7 +233,7 @@ Set resource type (Required if resource's name is used). =item B<--metric> -Set monitor metrics (Required) (Can be multiple). +Set monitor metrics (Required) (can be defined multiple times). =item B<--metric-namespace> diff --git a/src/cloud/azure/management/monitor/mode/health.pm b/src/cloud/azure/management/monitor/mode/health.pm index 22438360b..62c86d3a4 100644 --- a/src/cloud/azure/management/monitor/mode/health.pm +++ b/src/cloud/azure/management/monitor/mode/health.pm @@ -131,7 +131,7 @@ __END__ =head1 MODE -Check resource health status. Usefull to determine host status (ie UP/DOWN). +Check resource health status. Useful to determine host status (ie UP/DOWN). =over 8 diff --git a/src/cloud/azure/management/recovery/mode/backupitemsstatus.pm b/src/cloud/azure/management/recovery/mode/backupitemsstatus.pm index 6bf84a87b..4c5fbaa63 100644 --- a/src/cloud/azure/management/recovery/mode/backupitemsstatus.pm +++ b/src/cloud/azure/management/recovery/mode/backupitemsstatus.pm @@ -202,12 +202,12 @@ Example: --filter-counters='^total-completed$' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{precheck_status}, %{last_backup_status}, %{display} +You can use the following variables: %{precheck_status}, %{last_backup_status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{precheck_status} ne "Passed" || %{last_backup_status} eq "Failed"'). -Can used special variables like: %{precheck_status}, %{last_backup_status}, %{display} +You can use the following variables: %{precheck_status}, %{last_backup_status}, %{display} =item B<--warning-*> diff --git a/src/cloud/azure/management/recovery/mode/backupjobsstatus.pm b/src/cloud/azure/management/recovery/mode/backupjobsstatus.pm index 0ef422622..b9f873a80 100644 --- a/src/cloud/azure/management/recovery/mode/backupjobsstatus.pm +++ b/src/cloud/azure/management/recovery/mode/backupjobsstatus.pm @@ -219,12 +219,12 @@ Default: all existing job statuses are displayed. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "Failed"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/cloud/azure/management/recovery/mode/replicationhealth.pm b/src/cloud/azure/management/recovery/mode/replicationhealth.pm index 3aba0935c..44d340385 100644 --- a/src/cloud/azure/management/recovery/mode/replicationhealth.pm +++ b/src/cloud/azure/management/recovery/mode/replicationhealth.pm @@ -158,22 +158,22 @@ Filter item name (Can be a regexp). =item B<--warning-replication-status> Set warning threshold for replication health (Default: '%{replication_status} eq "Warning"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-replication-status> Set critical threshold for replication health (Default: '%{replication_status} eq "Critical"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-failover-status> Set warning threshold for failover status (Default: '%{failover_status} eq "Warning"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-failover-status> Set critical threshold for failover status (Default: '%{failover_status} eq "Critical"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/cloud/azure/management/resource/mode/deploymentsstatus.pm b/src/cloud/azure/management/resource/mode/deploymentsstatus.pm index b5db2056a..35501a437 100644 --- a/src/cloud/azure/management/resource/mode/deploymentsstatus.pm +++ b/src/cloud/azure/management/resource/mode/deploymentsstatus.pm @@ -179,12 +179,12 @@ Example: --filter-counters='^total-succeeded$' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "Succeeded"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/cloud/azure/network/appgateway/mode/health.pm b/src/cloud/azure/network/appgateway/mode/health.pm index 41ecdf986..b1102c89d 100644 --- a/src/cloud/azure/network/appgateway/mode/health.pm +++ b/src/cloud/azure/network/appgateway/mode/health.pm @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/network/expressroute/mode/circuitstatus.pm b/src/cloud/azure/network/expressroute/mode/circuitstatus.pm index 1c5045ac8..68df47ea8 100644 --- a/src/cloud/azure/network/expressroute/mode/circuitstatus.pm +++ b/src/cloud/azure/network/expressroute/mode/circuitstatus.pm @@ -141,12 +141,12 @@ Filter circuit name (Can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{circuit_status}, %{provider_status}, %{display} +You can use the following variables: %{circuit_status}, %{provider_status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{circuit_status} ne "Enabled" || %{provider_status} ne "Provisioned"'). -Can used special variables like: %{circuit_status}, %{provider_status}, %{display} +You can use the following variables: %{circuit_status}, %{provider_status}, %{display} =back diff --git a/src/cloud/azure/network/expressroute/mode/health.pm b/src/cloud/azure/network/expressroute/mode/health.pm index c31530c90..2c956ca4c 100644 --- a/src/cloud/azure/network/expressroute/mode/health.pm +++ b/src/cloud/azure/network/expressroute/mode/health.pm @@ -41,7 +41,7 @@ __END__ Check ExpressRoute Circuit health status. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/network/virtualnetwork/mode/peeringsstatus.pm b/src/cloud/azure/network/virtualnetwork/mode/peeringsstatus.pm index b75c068e0..f63daa001 100644 --- a/src/cloud/azure/network/virtualnetwork/mode/peeringsstatus.pm +++ b/src/cloud/azure/network/virtualnetwork/mode/peeringsstatus.pm @@ -158,12 +158,12 @@ Filter peering name (Can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{peering_state}, %{provisioning_state}, %{peer}, %{display} +You can use the following variables: %{peering_state}, %{provisioning_state}, %{peer}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{peering_state} ne "Connected" || %{provisioning_state} ne "Succeeded"'). -Can used special variables like: %{peering_state}, %{provisioning_state}, %{peer}, %{display} +You can use the following variables: %{peering_state}, %{provisioning_state}, %{peer}, %{display} =back diff --git a/src/cloud/azure/network/vpngateway/mode/health.pm b/src/cloud/azure/network/vpngateway/mode/health.pm index 25347bc39..079014d60 100644 --- a/src/cloud/azure/network/vpngateway/mode/health.pm +++ b/src/cloud/azure/network/vpngateway/mode/health.pm @@ -41,7 +41,7 @@ __END__ Check Virtual Machine health status. -(Usefull to determine host status) +(Useful to determine host status) =over 8 @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/network/vpngateway/mode/vpngatewaystatus.pm b/src/cloud/azure/network/vpngateway/mode/vpngatewaystatus.pm index 2dde9f73c..501591669 100644 --- a/src/cloud/azure/network/vpngateway/mode/vpngatewaystatus.pm +++ b/src/cloud/azure/network/vpngateway/mode/vpngatewaystatus.pm @@ -136,12 +136,12 @@ Filter vpn name (Can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{provisioning_state}, %{gateway_type}, %{vpn_type}, %{display} +You can use the following variables: %{provisioning_state}, %{gateway_type}, %{vpn_type}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{provisioning_state} ne "Succeeded"'). -Can used special variables like: %{provisioning_state}, %{gateway_type}, %{vpn_type}, %{display} +You can use the following variables: %{provisioning_state}, %{gateway_type}, %{vpn_type}, %{display} =back diff --git a/src/cloud/azure/web/appserviceplan/mode/health.pm b/src/cloud/azure/web/appserviceplan/mode/health.pm index 7ead74b96..5efc7b50c 100644 --- a/src/cloud/azure/web/appserviceplan/mode/health.pm +++ b/src/cloud/azure/web/appserviceplan/mode/health.pm @@ -56,22 +56,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/azure/web/signalr/mode/health.pm b/src/cloud/azure/web/signalr/mode/health.pm index 6b6a4f95d..2b0eba47f 100644 --- a/src/cloud/azure/web/signalr/mode/health.pm +++ b/src/cloud/azure/web/signalr/mode/health.pm @@ -54,22 +54,22 @@ Set resource group (Required if resource's name is used). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^Unavailable$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /^Unknown$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =item B<--ok-status> Set ok threshold for status (Default: '%{status} =~ /^Available$/'). -Can used special variables like: %{status}, %{summary} +You can use the following variables: %{status}, %{summary} =back diff --git a/src/cloud/docker/restapi/mode/containerusage.pm b/src/cloud/docker/restapi/mode/containerusage.pm index 3f6a8ed02..ffed712f4 100644 --- a/src/cloud/docker/restapi/mode/containerusage.pm +++ b/src/cloud/docker/restapi/mode/containerusage.pm @@ -346,12 +346,12 @@ Example: --filter-counters='^container-status$' =item B<--warning-container-status> Set warning threshold for status. -Can used special variables like: %{name}, %{state}, %{health}. +You can use the following variables: %{name}, %{state}, %{health}. =item B<--critical-container-status> Set critical threshold for status. -Can used special variables like: %{name}, %{state}, %{health}. +You can use the following variables: %{name}, %{state}, %{health}. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/docker/restapi/mode/nodestatus.pm b/src/cloud/docker/restapi/mode/nodestatus.pm index a0b491afa..594c725e0 100644 --- a/src/cloud/docker/restapi/mode/nodestatus.pm +++ b/src/cloud/docker/restapi/mode/nodestatus.pm @@ -140,12 +140,12 @@ Check node status. =item B<--warning-node-status> Set warning threshold for status (Default: -) -Can used special variables like: %{display}, %{status}, %{manager_status}. +You can use the following variables: %{display}, %{status}, %{manager_status}. =item B<--critical-node-status> Set critical threshold for status (Default: '%{status} !~ /ready/ || %{manager_status} !~ /reachable|-/'). -Can used special variables like: %{display}, %{status}, %{manager_status}. +You can use the following variables: %{display}, %{status}, %{manager_status}. =item B<--warning-*> diff --git a/src/cloud/docker/restapi/mode/servicestatus.pm b/src/cloud/docker/restapi/mode/servicestatus.pm index 48c3a5e10..2e0a7d81f 100644 --- a/src/cloud/docker/restapi/mode/servicestatus.pm +++ b/src/cloud/docker/restapi/mode/servicestatus.pm @@ -156,17 +156,17 @@ Filter service by service name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{service_id}, %{task_id}, %{service_name}, %{node_name}, %{node_id}, %{desired_state}, %{state_message}, %{container_id}. +You can use the following variables: %{service_id}, %{task_id}, %{service_name}, %{node_name}, %{node_id}, %{desired_state}, %{state_message}, %{container_id}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{service_id}, %{task_id}, %{service_name}, %{node_name}, %{node_id}, %{desired_state}, %{state_message}, %{container_id}. +You can use the following variables: %{service_id}, %{task_id}, %{service_name}, %{node_name}, %{node_id}, %{desired_state}, %{state_message}, %{container_id}. =item B<--critical-status> Set critical threshold for status (Default: '%{desired_state} ne %{state} and %{state} !~ /complete|preparing|assigned/'). -Can used special variables like: %{service_id}, %{task_id}, %{service_name}, %{node_name}, %{node_id}, %{desired_state}, %{state_message}, %{container_id}. +You can use the following variables: %{service_id}, %{task_id}, %{service_name}, %{node_name}, %{node_id}, %{desired_state}, %{state_message}, %{container_id}. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/cloudsql/common/mode/cpu.pm b/src/cloud/google/gcp/cloudsql/common/mode/cpu.pm index 3862baa12..5c678abd2 100644 --- a/src/cloud/google/gcp/cloudsql/common/mode/cpu.pm +++ b/src/cloud/google/gcp/cloudsql/common/mode/cpu.pm @@ -130,7 +130,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/cloudsql/common/mode/network.pm b/src/cloud/google/gcp/cloudsql/common/mode/network.pm index 08e6a04e8..4301222a4 100644 --- a/src/cloud/google/gcp/cloudsql/common/mode/network.pm +++ b/src/cloud/google/gcp/cloudsql/common/mode/network.pm @@ -159,7 +159,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/cloudsql/common/mode/storage.pm b/src/cloud/google/gcp/cloudsql/common/mode/storage.pm index 51a8e4e88..7e307dddd 100644 --- a/src/cloud/google/gcp/cloudsql/common/mode/storage.pm +++ b/src/cloud/google/gcp/cloudsql/common/mode/storage.pm @@ -148,7 +148,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/cloudsql/mysql/mode/innodb.pm b/src/cloud/google/gcp/cloudsql/mysql/mode/innodb.pm index b63ac3ff9..f8236b2dd 100644 --- a/src/cloud/google/gcp/cloudsql/mysql/mode/innodb.pm +++ b/src/cloud/google/gcp/cloudsql/mysql/mode/innodb.pm @@ -173,7 +173,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/cloudsql/mysql/mode/queries.pm b/src/cloud/google/gcp/cloudsql/mysql/mode/queries.pm index 4bd762623..f91938494 100644 --- a/src/cloud/google/gcp/cloudsql/mysql/mode/queries.pm +++ b/src/cloud/google/gcp/cloudsql/mysql/mode/queries.pm @@ -138,7 +138,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/compute/computeengine/mode/cpu.pm b/src/cloud/google/gcp/compute/computeengine/mode/cpu.pm index b45dc2402..93da84f2b 100644 --- a/src/cloud/google/gcp/compute/computeengine/mode/cpu.pm +++ b/src/cloud/google/gcp/compute/computeengine/mode/cpu.pm @@ -130,7 +130,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/compute/computeengine/mode/diskio.pm b/src/cloud/google/gcp/compute/computeengine/mode/diskio.pm index 6860fbd9d..f94c33995 100644 --- a/src/cloud/google/gcp/compute/computeengine/mode/diskio.pm +++ b/src/cloud/google/gcp/compute/computeengine/mode/diskio.pm @@ -212,7 +212,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/compute/computeengine/mode/network.pm b/src/cloud/google/gcp/compute/computeengine/mode/network.pm index 0e8037278..42db9fe9d 100644 --- a/src/cloud/google/gcp/compute/computeengine/mode/network.pm +++ b/src/cloud/google/gcp/compute/computeengine/mode/network.pm @@ -178,7 +178,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/google/gcp/custom/api.pm b/src/cloud/google/gcp/custom/api.pm index f31f2ac73..11941cfb3 100644 --- a/src/cloud/google/gcp/custom/api.pm +++ b/src/cloud/google/gcp/custom/api.pm @@ -474,7 +474,7 @@ Google Cloud Platform Rest API To connect to the GCP Rest API, you need to create an API key. -Follow the 'How-to guide' in https://cloud.google.com/video-intelligence/docs/common/auth +Follow the 'How-to guide' at https://cloud.google.com/video-intelligence/docs/common/auth =over 8 @@ -496,7 +496,7 @@ Set GCP scope endpoint URL (Default: 'https://www.googleapis.com/auth/cloud-plat =item B<--zeroed> -Set metrics value to 0 if none. Usefull when Stackdriver +Set metrics value to 0 if none. Useful when Stackdriver does not return value when not defined. =item B<--timeout> diff --git a/src/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm b/src/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm index d6c19d04b..688a5b9b4 100644 --- a/src/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm +++ b/src/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm @@ -231,7 +231,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-metric> @@ -243,7 +245,7 @@ Threshold critical. =item B<--extra-filter> -Set extra filters (Can be multiple). +Set extra filters (can be defined multiple times). Example: --extra-filter='metric.labels.mylabel = "LABELBLEUE"' diff --git a/src/cloud/google/gcp/storage/mode/bucket.pm b/src/cloud/google/gcp/storage/mode/bucket.pm index 51019ad28..e807c8a8b 100644 --- a/src/cloud/google/gcp/storage/mode/bucket.pm +++ b/src/cloud/google/gcp/storage/mode/bucket.pm @@ -159,7 +159,9 @@ Set timeframe in seconds (i.e. 3600 to check last hour). =item B<--aggregation> -Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). +Aggregate monitoring. Can apply to: 'minimum', 'maximum', 'average', 'total' +and 'count'. +Can be called multiple times. =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/ibm/softlayer/mode/events.pm b/src/cloud/ibm/softlayer/mode/events.pm index 40547ebee..be25c11fe 100644 --- a/src/cloud/ibm/softlayer/mode/events.pm +++ b/src/cloud/ibm/softlayer/mode/events.pm @@ -199,13 +199,13 @@ Filter events status (Default: 'Active') =item B<--warning-event> Set warning threshold for status. -Can used special variables like: %{id}, %{subject}, %{status}, %{items}, +You can use the following variables: %{id}, %{subject}, %{status}, %{items}, %{start_date}, %{since_start}, %{end_date}, %{since_end}. =item B<--critical-event> Set critical threshold for status (Default: '%{status} =~ /Active/ && %{items} > 0'). -Can used special variables like: %{id}, %{subject}, %{status}, %{items}, +You can use the following variables: %{id}, %{subject}, %{status}, %{items}, %{start_date}, %{since_start}, %{end_date}, %{since_end}. =item B<--warning-*> diff --git a/src/cloud/ibm/softlayer/mode/opentickets.pm b/src/cloud/ibm/softlayer/mode/opentickets.pm index 47945b7d9..4f6635055 100644 --- a/src/cloud/ibm/softlayer/mode/opentickets.pm +++ b/src/cloud/ibm/softlayer/mode/opentickets.pm @@ -159,12 +159,12 @@ Name of the ticket group (Can be a regexp). =item B<--warning-ticket> Set warning threshold for status. -Can used special variables like: %{id}, %{title}, %{priority}, %{create_date}, %{group}, %{since}. +You can use the following variables: %{id}, %{title}, %{priority}, %{create_date}, %{group}, %{since}. =item B<--critical-ticket> Set critical threshold for status. -Can used special variables like: %{id}, %{title}, %{priority}, %{create_date}, %{group}, %{since}. +You can use the following variables: %{id}, %{title}, %{priority}, %{create_date}, %{group}, %{since}. =item B<--warning-open> diff --git a/src/cloud/iics/restapi/mode/agents.pm b/src/cloud/iics/restapi/mode/agents.pm index ca8f84321..4b29634af 100644 --- a/src/cloud/iics/restapi/mode/agents.pm +++ b/src/cloud/iics/restapi/mode/agents.pm @@ -224,32 +224,32 @@ Filter agents if active or not. =item B<--unknown-agent-status> Set unknown threshold for status. -Can used special variables like: %{active}, %{readyToRun}, %{id}, %{name} +You can use the following variables: %{active}, %{readyToRun}, %{id}, %{name} =item B<--warning-agent-status> Set warning threshold for status. -Can used special variables like: %{active}, %{readyToRun}, %{id}, %{name} +You can use the following variables: %{active}, %{readyToRun}, %{id}, %{name} =item B<--critical-agent-status> Set critical threshold for status (Default: '%{active} eq "yes" and %{readyToRun} eq "no"'). -Can used special variables like: %{active}, %{readyToRun}, %{id}, %{name} +You can use the following variables: %{active}, %{readyToRun}, %{id}, %{name} =item B<--unknown-engine-status> Set unknown threshold for status. -Can used special variables like: %{agentName}, %{appDisplayName}, %{status}, %{desiredStatus} +You can use the following variables: %{agentName}, %{appDisplayName}, %{status}, %{desiredStatus} =item B<--warning-engine-status> Set warning threshold for status. -Can used special variables like: %{agentName}, %{appDisplayName}, %{status}, %{desiredStatus} +You can use the following variables: %{agentName}, %{appDisplayName}, %{status}, %{desiredStatus} =item B<--critical-engine-status> Set critical threshold for status. -Can used special variables like: %{agentName}, %{appDisplayName}, %{status}, %{desiredStatus} +You can use the following variables: %{agentName}, %{appDisplayName}, %{status}, %{desiredStatus} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/kubernetes/mode/cronjobstatus.pm b/src/cloud/kubernetes/mode/cronjobstatus.pm index 18fe569db..312ada14a 100644 --- a/src/cloud/kubernetes/mode/cronjobstatus.pm +++ b/src/cloud/kubernetes/mode/cronjobstatus.pm @@ -168,13 +168,13 @@ Filter CronJob namespace (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{name}, %{namespace}, %{active}, +You can use the following variables: %{name}, %{namespace}, %{active}, %{last_schedule}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{name}, %{namespace}, %{active}, +You can use the following variables: %{name}, %{namespace}, %{active}, %{last_schedule}. =back diff --git a/src/cloud/kubernetes/mode/daemonsetstatus.pm b/src/cloud/kubernetes/mode/daemonsetstatus.pm index ab876fa9c..43d672936 100644 --- a/src/cloud/kubernetes/mode/daemonsetstatus.pm +++ b/src/cloud/kubernetes/mode/daemonsetstatus.pm @@ -186,13 +186,13 @@ Filter DaemonSet namespace (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{up_to_date} < %{desired}') -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date}, %{ready}, %{misscheduled}. =item B<--critical-status> Set critical threshold for status (Default: '%{available} < %{desired}'). -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date}, %{ready}, %{misscheduled}. =back diff --git a/src/cloud/kubernetes/mode/deploymentstatus.pm b/src/cloud/kubernetes/mode/deploymentstatus.pm index fdfc6f296..6f81de707 100644 --- a/src/cloud/kubernetes/mode/deploymentstatus.pm +++ b/src/cloud/kubernetes/mode/deploymentstatus.pm @@ -173,13 +173,13 @@ Filter deployment namespace (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{up_to_date} < %{desired}') -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date}. =item B<--critical-status> Set critical threshold for status (Default: '%{available} < %{desired}'). -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date}. =back diff --git a/src/cloud/kubernetes/mode/nodestatus.pm b/src/cloud/kubernetes/mode/nodestatus.pm index c40ebd6ff..eeefb52b3 100644 --- a/src/cloud/kubernetes/mode/nodestatus.pm +++ b/src/cloud/kubernetes/mode/nodestatus.pm @@ -147,12 +147,12 @@ Filter node name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{type}, %{status}, %{reason}, %{message}, %{name}. +You can use the following variables: %{type}, %{status}, %{reason}, %{message}, %{name}. =item B<--critical-status> Set critical threshold for status (Default: '(%{type} =~ /Ready/i && %{status} !~ /True/i) || (%{type} =~ /.*Pressure/i && %{status} !~ /False/i)'). -Can used special variables like: %{type}, %{status}, %{reason}, %{message}, %{name}. +You can use the following variables: %{type}, %{status}, %{reason}, %{message}, %{name}. =back diff --git a/src/cloud/kubernetes/mode/persistentvolumestatus.pm b/src/cloud/kubernetes/mode/persistentvolumestatus.pm index 95a6adac5..54bfd7fd0 100644 --- a/src/cloud/kubernetes/mode/persistentvolumestatus.pm +++ b/src/cloud/kubernetes/mode/persistentvolumestatus.pm @@ -116,12 +116,12 @@ Filter persistent volume name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{name}, %{phase}. +You can use the following variables: %{name}, %{phase}. =item B<--critical-status> Set critical threshold for status (Default: '%{phase} !~ /Bound|Available|Released/i'). -Can used special variables like: %{name}, %{phase}. +You can use the following variables: %{name}, %{phase}. =back diff --git a/src/cloud/kubernetes/mode/podstatus.pm b/src/cloud/kubernetes/mode/podstatus.pm index 144ac8741..a8c4287f0 100644 --- a/src/cloud/kubernetes/mode/podstatus.pm +++ b/src/cloud/kubernetes/mode/podstatus.pm @@ -298,29 +298,29 @@ Filter pod namespace (can be a regexp). =item B<--extra-filter> -Add an extra filter based on labels (Can be multiple) +Add an extra filter based on labels (can be defined multiple times) Example : --extra-filter='app=mynewapp' =item B<--warning-pod-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{name}, %{namespace}. +You can use the following variables: %{status}, %{name}, %{namespace}. =item B<--critical-pod-status> Set critical threshold for status (Default: '%{status} !~ /running/i'). -Can used special variables like: %{status}, %{name}, %{namespace}. +You can use the following variables: %{status}, %{name}, %{namespace}. =item B<--warning-container-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{name}. +You can use the following variables: %{status}, %{name}. =item B<--critical-container-status> Set critical threshold for status (Default: '%{status} !~ /running/i || %{state} !~ /^ready$/'). -Can used special variables like: %{status}, %{state}, %{name}. +You can use the following variables: %{status}, %{state}, %{name}. =item B<--warning-*> diff --git a/src/cloud/kubernetes/mode/replicasetstatus.pm b/src/cloud/kubernetes/mode/replicasetstatus.pm index c55e40c2d..8ec4b24b6 100644 --- a/src/cloud/kubernetes/mode/replicasetstatus.pm +++ b/src/cloud/kubernetes/mode/replicasetstatus.pm @@ -153,13 +153,13 @@ Filter ReplicaSet namespace (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{ready}. =item B<--critical-status> Set critical threshold for status (Default: '%{ready} < %{desired}'). -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{ready}. =back diff --git a/src/cloud/kubernetes/mode/replicationcontrollerstatus.pm b/src/cloud/kubernetes/mode/replicationcontrollerstatus.pm index 79cf60248..bce3cd5af 100644 --- a/src/cloud/kubernetes/mode/replicationcontrollerstatus.pm +++ b/src/cloud/kubernetes/mode/replicationcontrollerstatus.pm @@ -153,13 +153,13 @@ Filter ReplicationController namespace (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{ready}. =item B<--critical-status> Set critical threshold for status (Default: '%{ready} < %{desired}'). -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{ready}. =back diff --git a/src/cloud/kubernetes/mode/statefulsetstatus.pm b/src/cloud/kubernetes/mode/statefulsetstatus.pm index 3b4622917..4bdbaa5eb 100644 --- a/src/cloud/kubernetes/mode/statefulsetstatus.pm +++ b/src/cloud/kubernetes/mode/statefulsetstatus.pm @@ -166,13 +166,13 @@ Filter StatefulSet namespace (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{up_to_date} < %{desired}') -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{up_to_date}, %{ready}. =item B<--critical-status> Set critical threshold for status (Default: '%{ready} < %{desired}'). -Can used special variables like: %{name}, %{namespace}, %{desired}, %{current}, +You can use the following variables: %{name}, %{namespace}, %{desired}, %{current}, %{up_to_date}, %{ready}. =back diff --git a/src/cloud/microsoft/office365/custom/graphapi.pm b/src/cloud/microsoft/office365/custom/graphapi.pm index b22f8fbac..b67e698a9 100644 --- a/src/cloud/microsoft/office365/custom/graphapi.pm +++ b/src/cloud/microsoft/office365/custom/graphapi.pm @@ -509,7 +509,7 @@ Microsoft Office 365 Graph API To connect to the Office 365 Graph API, you must register an application. -Follow the 'How-to guide' in https://docs.microsoft.com/en-us/graph/auth-register-app-v2?view=graph-rest-1.0 +Follow the 'How-to guide' at https://docs.microsoft.com/en-us/graph/auth-register-app-v2?view=graph-rest-1.0 This custom mode is using the 'OAuth 2.0 Client Credentials Grant Flow'. diff --git a/src/cloud/microsoft/office365/custom/managementapi.pm b/src/cloud/microsoft/office365/custom/managementapi.pm index 5d7d7c5cf..ea77e7b6e 100644 --- a/src/cloud/microsoft/office365/custom/managementapi.pm +++ b/src/cloud/microsoft/office365/custom/managementapi.pm @@ -251,7 +251,7 @@ Microsoft Office 365 Management API To connect to the Office 365 Management API, you must register an application. -Follow the 'How-to guide' in https://docs.microsoft.com/en-us/office/office-365-management-api/get-started-with-office-365-management-apis#register-your-application-in-azure-ad +Follow the 'How-to guide' at https://docs.microsoft.com/en-us/office/office-365-management-api/get-started-with-office-365-management-apis#register-your-application-in-azure-ad This custom mode is using the 'OAuth 2.0 Client Credentials Grant Flow'. diff --git a/src/cloud/microsoft/office365/exchange/mode/mailboxusage.pm b/src/cloud/microsoft/office365/exchange/mode/mailboxusage.pm index c6c8417c6..f98aeedc2 100644 --- a/src/cloud/microsoft/office365/exchange/mode/mailboxusage.pm +++ b/src/cloud/microsoft/office365/exchange/mode/mailboxusage.pm @@ -304,13 +304,13 @@ Can be: 'active-mailboxes', 'total-usage-active' (count), =item B<--warning-status> Set warning threshold for status (Default: '%{used} > %{issue_warning_quota}'). -Can used special variables like: %{used}, %{issue_warning_quota}, +You can use the following variables: %{used}, %{issue_warning_quota}, %{prohibit_send_quota}, %{prohibit_send_receive_quota} =item B<--critical-status> Set critical threshold for status (Default: '%{used} > %{prohibit_send_quota}'). -Can used special variables like: %{used}, %{issue_warning_quota}, +You can use the following variables: %{used}, %{issue_warning_quota}, %{prohibit_send_quota}, %{prohibit_send_receive_quota} =item B<--filter-counters> diff --git a/src/cloud/microsoft/office365/management/mode/appcredentials.pm b/src/cloud/microsoft/office365/management/mode/appcredentials.pm index e64cad2a2..344662d5e 100644 --- a/src/cloud/microsoft/office365/management/mode/appcredentials.pm +++ b/src/cloud/microsoft/office365/management/mode/appcredentials.pm @@ -239,22 +239,22 @@ Filter applications (can be a regexp). =item B<--warning-key-status> Set warning threshold for status. -Can used special variables like: %{status}, %{id}, %{app_name}. +You can use the following variables: %{status}, %{id}, %{app_name}. =item B<--critical-key-status> Set critical threshold for status (Default: '%{status} =~ /expired/i'). -Can used special variables like: %{status}, %{id}, %{app_name}. +You can use the following variables: %{status}, %{id}, %{app_name}. =item B<--warning-password-status> Set warning threshold for status. -Can used special variables like: %{status}, %{id}, %{app_name}. +You can use the following variables: %{status}, %{id}, %{app_name}. =item B<--critical-password-status> Set critical threshold for status (Default: '%{status} =~ /expired/i'). -Can used special variables like: %{status}, %{id}, %{app_name}. +You can use the following variables: %{status}, %{id}, %{app_name}. =item B<--unit> diff --git a/src/cloud/microsoft/office365/management/mode/servicestatus.pm b/src/cloud/microsoft/office365/management/mode/servicestatus.pm index 817838007..b656f1e58 100644 --- a/src/cloud/microsoft/office365/management/mode/servicestatus.pm +++ b/src/cloud/microsoft/office365/management/mode/servicestatus.pm @@ -136,12 +136,12 @@ Filter services (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{service_name}, %{status}, %{classification} +You can use the following variables: %{service_name}, %{status}, %{classification} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /serviceOperational|serviceRestored/i'). -Can used special variables like: %{service_name}, %{status}, %{classification} +You can use the following variables: %{service_name}, %{status}, %{classification} =back diff --git a/src/cloud/microsoft/office365/management/mode/subscriptions.pm b/src/cloud/microsoft/office365/management/mode/subscriptions.pm index 258355f57..80ab644f8 100644 --- a/src/cloud/microsoft/office365/management/mode/subscriptions.pm +++ b/src/cloud/microsoft/office365/management/mode/subscriptions.pm @@ -167,12 +167,12 @@ Filter subscriptions by SKU part number (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{capabilityStatus}, %{skuPartNumber} +You can use the following variables: %{capabilityStatus}, %{skuPartNumber} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{capabilityStatus}, %{skuPartNumber} +You can use the following variables: %{capabilityStatus}, %{skuPartNumber} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/nutanix/snmp/mode/clusterusage.pm b/src/cloud/nutanix/snmp/mode/clusterusage.pm index 059c2c2a1..9ef652817 100644 --- a/src/cloud/nutanix/snmp/mode/clusterusage.pm +++ b/src/cloud/nutanix/snmp/mode/clusterusage.pm @@ -237,12 +237,12 @@ Example: --filter-counters='^usage$' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/cloud/nutanix/snmp/mode/diskusage.pm b/src/cloud/nutanix/snmp/mode/diskusage.pm index 82e674d14..9ddd7806c 100644 --- a/src/cloud/nutanix/snmp/mode/diskusage.pm +++ b/src/cloud/nutanix/snmp/mode/diskusage.pm @@ -354,12 +354,12 @@ Filter controllervm name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{crtName}, %{diskId} +You can use the following variables: %{state}, %{crtName}, %{diskId} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{crtName}, %{diskId} +You can use the following variables: %{state}, %{crtName}, %{diskId} =item B<--warning-*> diff --git a/src/cloud/nutanix/snmp/mode/vmusage.pm b/src/cloud/nutanix/snmp/mode/vmusage.pm index 4d54fc54c..560dd15fc 100644 --- a/src/cloud/nutanix/snmp/mode/vmusage.pm +++ b/src/cloud/nutanix/snmp/mode/vmusage.pm @@ -271,12 +271,12 @@ Filter virtual machine name (can be a regexp). =item B<--warning-vm-power-state> Set warning threshold for the virtual machine power state. -Can used special variables like: %{vmPowerState}. +You can use the following variables: %{vmPowerState}. =item B<--critical-vm-power-state> Set critical threshold for the virtual machine power state. -Can used special variables like: %{vmPowerState}. +You can use the following variables: %{vmPowerState}. =item B<--warning-*> diff --git a/src/cloud/outscale/mode/clientgateways.pm b/src/cloud/outscale/mode/clientgateways.pm index 6652e5891..77b15619f 100644 --- a/src/cloud/outscale/mode/clientgateways.pm +++ b/src/cloud/outscale/mode/clientgateways.pm @@ -175,17 +175,17 @@ Client gateway tags to be used for the name (Default: 'name'). =item B<--unknown-cg-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{cgName} +You can use the following variables: %{state}, %{cgName} =item B<--warning-cg-status> Set warning threshold for status. -Can used special variables like: %{state}, %{cgName} +You can use the following variables: %{state}, %{cgName} =item B<--critical-cg-status> Set critical threshold for status. -Can used special variables like: %{state}, %{cgName} +You can use the following variables: %{state}, %{cgName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/internetservices.pm b/src/cloud/outscale/mode/internetservices.pm index 9f2a50e8c..661ea1373 100644 --- a/src/cloud/outscale/mode/internetservices.pm +++ b/src/cloud/outscale/mode/internetservices.pm @@ -152,17 +152,17 @@ Internet service tag to be used for the name (Default: 'name'). =item B<--unknown-internet-service-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{internetServiceName} +You can use the following variables: %{state}, %{internetServiceName} =item B<--warning-internet-service-status> Set warning threshold for status. -Can used special variables like: %{state}, %{internetServiceName} +You can use the following variables: %{state}, %{internetServiceName} =item B<--critical-internet-service-status> Set critical threshold for status. -Can used special variables like: %{state}, %{internetServiceName} +You can use the following variables: %{state}, %{internetServiceName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/loadbalancers.pm b/src/cloud/outscale/mode/loadbalancers.pm index 2db9d662d..2c78ebcea 100644 --- a/src/cloud/outscale/mode/loadbalancers.pm +++ b/src/cloud/outscale/mode/loadbalancers.pm @@ -203,17 +203,17 @@ Virtual machine tags to used for the name (Default: 'name'). =item B<--unknown-vm-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{vmName} +You can use the following variables: %{state}, %{vmName} =item B<--warning-vm-status> Set warning threshold for status. -Can used special variables like: %{state}, %{vmName} +You can use the following variables: %{state}, %{vmName} =item B<--critical-vm-status> Set critical threshold for status. -Can used special variables like: %{state}, %{vmName} +You can use the following variables: %{state}, %{vmName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/natservices.pm b/src/cloud/outscale/mode/natservices.pm index e8b6a8ffe..c925fbf7b 100644 --- a/src/cloud/outscale/mode/natservices.pm +++ b/src/cloud/outscale/mode/natservices.pm @@ -152,17 +152,17 @@ Nat service tag to be used for the name (Default: 'name'). =item B<--unknown-nat-service-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{natName} +You can use the following variables: %{state}, %{natName} =item B<--warning-nat-service-status> Set warning threshold for status. -Can used special variables like: %{state}, %{natName} +You can use the following variables: %{state}, %{natName} =item B<--critical-nat-service-status> Set critical threshold for status. -Can used special variables like: %{state}, %{natName} +You can use the following variables: %{state}, %{natName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/nets.pm b/src/cloud/outscale/mode/nets.pm index ec15197d2..a27a062f5 100644 --- a/src/cloud/outscale/mode/nets.pm +++ b/src/cloud/outscale/mode/nets.pm @@ -145,17 +145,17 @@ Nets tag to be used for the name (Default: 'name'). =item B<--unknown-net-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{netName} +You can use the following variables: %{state}, %{netName} =item B<--warning-net-status> Set warning threshold for status. -Can used special variables like: %{state}, %{netName} +You can use the following variables: %{state}, %{netName} =item B<--critical-net-status> Set critical threshold for status. -Can used special variables like: %{state}, %{netName} +You can use the following variables: %{state}, %{netName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/quotas.pm b/src/cloud/outscale/mode/quotas.pm index 268c01151..e7afac10e 100644 --- a/src/cloud/outscale/mode/quotas.pm +++ b/src/cloud/outscale/mode/quotas.pm @@ -177,17 +177,17 @@ Nets tag to be used for the name (Default: 'name'). =item B<--unknown-net-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{netName} +You can use the following variables: %{state}, %{netName} =item B<--warning-net-status> Set warning threshold for status. -Can used special variables like: %{state}, %{netName} +You can use the following variables: %{state}, %{netName} =item B<--critical-net-status> Set critical threshold for status. -Can used special variables like: %{state}, %{netName} +You can use the following variables: %{state}, %{netName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/subnets.pm b/src/cloud/outscale/mode/subnets.pm index b840b9c01..8df7d2b70 100644 --- a/src/cloud/outscale/mode/subnets.pm +++ b/src/cloud/outscale/mode/subnets.pm @@ -190,17 +190,17 @@ Subnet tags to be used for the name (Default: 'name'). =item B<--unknown-subnet-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{subnetName} +You can use the following variables: %{state}, %{subnetName} =item B<--warning-subnet-status> Set warning threshold for status. -Can used special variables like: %{state}, %{subnetName} +You can use the following variables: %{state}, %{subnetName} =item B<--critical-subnet-status> Set critical threshold for status. -Can used special variables like: %{state}, %{subnetName} +You can use the following variables: %{state}, %{subnetName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/virtualgateways.pm b/src/cloud/outscale/mode/virtualgateways.pm index bc3c4ad0b..20c72f2ef 100644 --- a/src/cloud/outscale/mode/virtualgateways.pm +++ b/src/cloud/outscale/mode/virtualgateways.pm @@ -175,17 +175,17 @@ Virtual gateway tag to be used for the name (Default: 'name'). =item B<--unknown-vg-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{vgName} +You can use the following variables: %{state}, %{vgName} =item B<--warning-vg-status> Set warning threshold for status. -Can used special variables like: %{state}, %{vgName} +You can use the following variables: %{state}, %{vgName} =item B<--critical-vg-status> Set critical threshold for status. -Can used special variables like: %{state}, %{vgName} +You can use the following variables: %{state}, %{vgName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/vms.pm b/src/cloud/outscale/mode/vms.pm index cfe8060ca..864138057 100644 --- a/src/cloud/outscale/mode/vms.pm +++ b/src/cloud/outscale/mode/vms.pm @@ -152,17 +152,17 @@ Virtual machine tag to be used for the name (Default: 'name'). =item B<--unknown-vm-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{vmName} +You can use the following variables: %{state}, %{vmName} =item B<--warning-vm-status> Set warning threshold for status. -Can used special variables like: %{state}, %{vmName} +You can use the following variables: %{state}, %{vmName} =item B<--critical-vm-status> Set critical threshold for status. -Can used special variables like: %{state}, %{vmName} +You can use the following variables: %{state}, %{vmName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/volumes.pm b/src/cloud/outscale/mode/volumes.pm index b32e86e54..8c06d7233 100644 --- a/src/cloud/outscale/mode/volumes.pm +++ b/src/cloud/outscale/mode/volumes.pm @@ -195,17 +195,17 @@ Virtual machine tags to used for the name (Default: 'name'). =item B<--unknown-volume-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{volumeId} +You can use the following variables: %{state}, %{volumeId} =item B<--warning-volume-status> Set warning threshold for status. -Can used special variables like: %{state}, %{volumeId} +You can use the following variables: %{state}, %{volumeId} =item B<--critical-volume-status> Set critical threshold for status. -Can used special variables like: %{state}, %{volumeId} +You can use the following variables: %{state}, %{volumeId} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/outscale/mode/vpnconnections.pm b/src/cloud/outscale/mode/vpnconnections.pm index a2d822dc7..41c292d15 100644 --- a/src/cloud/outscale/mode/vpnconnections.pm +++ b/src/cloud/outscale/mode/vpnconnections.pm @@ -192,17 +192,17 @@ Vpn connection tag to be used for the name (Default: 'name'). =item B<--unknown-vpn-connection-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{vpnName} +You can use the following variables: %{state}, %{vpnName} =item B<--warning-vpn-connection-status> Set warning threshold for status. -Can used special variables like: %{state}, %{vpnName} +You can use the following variables: %{state}, %{vpnName} =item B<--critical-vpn-connection-status> Set critical threshold for status. -Can used special variables like: %{state}, %{vpnName} +You can use the following variables: %{state}, %{vpnName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm b/src/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm index a682a756a..2f6e05784 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm @@ -216,12 +216,12 @@ Filter on a specific pod (Must be a PromQL filter, Default: 'pod=~".*"') =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{status}, %{state}, %{reason} +You can use the following variables: %{status}, %{state}, %{reason} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /running/ || %{state} !~ /ready/'). -Can used special variables like: %{status}, %{state}, %{reason} +You can use the following variables: %{status}, %{state}, %{reason} =item B<--warning-restarts-count> @@ -233,13 +233,13 @@ Threshold critical for container restarts count. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm b/src/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm index d4ca8abba..541adc54d 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm @@ -240,24 +240,24 @@ Filter on a specific daemonset (Must be a PromQL filter, Default: 'daemonset=~". =item B<--warning-status> Set warning threshold for status (Default: '%{up_to_date} < %{desired}') -Can used special variables like: %{display}, %{desired}, %{current}, +You can use the following variables: %{display}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date}, %{ready}, %{misscheduled} =item B<--critical-status> Set critical threshold for status (Default: '%{available} < %{desired}'). -Can used special variables like: %{display}, %{desired}, %{current}, +You can use the following variables: %{display}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date}, %{ready}, %{misscheduled} =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm b/src/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm index 63f3dfd4a..66a1660b1 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm @@ -215,24 +215,24 @@ Filter on a specific deployment (Must be a PromQL filter, Default: 'deployment=~ =item B<--warning-status> Set warning threshold for status (Default: '%{up_to_date} < %{desired}') -Can used special variables like: %{display}, %{desired}, %{current}, +You can use the following variables: %{display}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date} =item B<--critical-status> Set critical threshold for status (Default: '%{available} < %{desired}'). -Can used special variables like: %{display}, %{desired}, %{current}, +You can use the following variables: %{display}, %{desired}, %{current}, %{available}, %{unavailable}, %{up_to_date} =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/listcontainers.pm b/src/cloud/prometheus/direct/kubernetes/mode/listcontainers.pm index 615f368d1..81d1f1723 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/listcontainers.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/listcontainers.pm @@ -144,13 +144,13 @@ Filter on a specific image (Must be a PromQL filter, Default: 'image=~".*"') =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'info') +Overload default metrics name (can be defined multiple times, metric can be 'info') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/listdaemonsets.pm b/src/cloud/prometheus/direct/kubernetes/mode/listdaemonsets.pm index f961e1f61..79ce1cd9e 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/listdaemonsets.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/listdaemonsets.pm @@ -130,13 +130,13 @@ Filter on a specific namespace (Must be a PromQL filter, Default: 'namespace=~". =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'created') +Overload default metrics name (can be defined multiple times, metric can be 'created') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/listdeployments.pm b/src/cloud/prometheus/direct/kubernetes/mode/listdeployments.pm index c80f2bf73..a94064cd3 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/listdeployments.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/listdeployments.pm @@ -123,13 +123,13 @@ Filter on a specific deployment (Must be a PromQL filter, Default: 'deployment=~ =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'labels') +Overload default metrics name (can be defined multiple times, metric can be 'labels') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/listnamespaces.pm b/src/cloud/prometheus/direct/kubernetes/mode/listnamespaces.pm index 4250b305a..39e27126b 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/listnamespaces.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/listnamespaces.pm @@ -123,13 +123,13 @@ Filter on a specific namespace (Must be a PromQL filter, Default: 'namespace=~". =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'labels') +Overload default metrics name (can be defined multiple times, metric can be 'labels') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/listnodes.pm b/src/cloud/prometheus/direct/kubernetes/mode/listnodes.pm index aa2d9cdf5..2a9351e99 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/listnodes.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/listnodes.pm @@ -162,13 +162,13 @@ Filter on a specific container runtime version (Must be a PromQL filter, Default =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'info') +Overload default metrics name (can be defined multiple times, metric can be 'info') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/listservices.pm b/src/cloud/prometheus/direct/kubernetes/mode/listservices.pm index c2147ca68..d3501ca8a 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/listservices.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/listservices.pm @@ -130,13 +130,13 @@ Filter on a specific cluster ip (Must be a PromQL filter, Default: 'cluster_ip=~ =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'info') +Overload default metrics name (can be defined multiple times, metric can be 'info') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm b/src/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm index 85cc05f96..7f345647c 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm @@ -193,22 +193,22 @@ Filter on a specific phase (Must be a PromQL filter, Default: 'phase=~".*"') =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{display}, %{phase}. +You can use the following variables: %{display}, %{phase}. =item B<--critical-status> Set critical threshold for status (Default: '%{phase} !~ /Active/'). -Can used special variables like: %{display}, %{phase} +You can use the following variables: %{display}, %{phase} =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm b/src/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm index 8075d7c22..c5c1d204a 100644 --- a/src/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm +++ b/src/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm @@ -252,12 +252,12 @@ Filter on a specific node (Must be a PromQL filter, Default: 'node=~".*"') =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{display}, %{status}, %{schedulable} +You can use the following variables: %{display}, %{status}, %{schedulable} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Ready/ || %{schedulable} != /false/'). -Can used special variables like: %{display}, %{status}, %{schedulable} +You can use the following variables: %{display}, %{status}, %{schedulable} =item B<--warning-allocated-pods> @@ -273,13 +273,13 @@ Units of thresholds (Default: '') (Can be '%'). =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm b/src/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm index bfe34aa02..ef4a66a83 100644 --- a/src/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm +++ b/src/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm @@ -169,13 +169,13 @@ Can be: 'reading', 'waiting', 'writing', 'active', =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm b/src/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm index d7b72a4f2..a4b08f68f 100644 --- a/src/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm +++ b/src/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm @@ -177,13 +177,13 @@ Can be: 'requests', 'requests-2xx', 'requests-3xx', =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/cadvisor/mode/cpu.pm b/src/cloud/prometheus/exporters/cadvisor/mode/cpu.pm index 067547209..c5ae662c2 100644 --- a/src/cloud/prometheus/exporters/cadvisor/mode/cpu.pm +++ b/src/cloud/prometheus/exporters/cadvisor/mode/cpu.pm @@ -180,13 +180,13 @@ Can be: 'usage', 'throttled'. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/cadvisor/mode/listcontainers.pm b/src/cloud/prometheus/exporters/cadvisor/mode/listcontainers.pm index 78fb18955..b0bc826b8 100644 --- a/src/cloud/prometheus/exporters/cadvisor/mode/listcontainers.pm +++ b/src/cloud/prometheus/exporters/cadvisor/mode/listcontainers.pm @@ -139,13 +139,13 @@ Filter on a specific namespace (Must be a PromQL filter, Default: 'namespace=~". =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple, metric can be 'last_seen') +Overload default metrics name (can be defined multiple times, metric can be 'last_seen') Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/cadvisor/mode/load.pm b/src/cloud/prometheus/exporters/cadvisor/mode/load.pm index b4dddf710..df9799850 100644 --- a/src/cloud/prometheus/exporters/cadvisor/mode/load.pm +++ b/src/cloud/prometheus/exporters/cadvisor/mode/load.pm @@ -157,13 +157,13 @@ Threshold critical. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/cadvisor/mode/memory.pm b/src/cloud/prometheus/exporters/cadvisor/mode/memory.pm index 2c5efc4c6..57bc259c5 100644 --- a/src/cloud/prometheus/exporters/cadvisor/mode/memory.pm +++ b/src/cloud/prometheus/exporters/cadvisor/mode/memory.pm @@ -302,13 +302,13 @@ Units of thresholds (Default: '%') ('%', 'B'). =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/cadvisor/mode/storage.pm b/src/cloud/prometheus/exporters/cadvisor/mode/storage.pm index dde363eb5..8a525d217 100644 --- a/src/cloud/prometheus/exporters/cadvisor/mode/storage.pm +++ b/src/cloud/prometheus/exporters/cadvisor/mode/storage.pm @@ -267,13 +267,13 @@ Threshold critical. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm b/src/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm index 988d33d26..47c963d46 100644 --- a/src/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm +++ b/src/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm @@ -199,13 +199,13 @@ Can be: 'sleeping', 'running', 'stopped', 'uninterruptible', 'iowaiting'. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm b/src/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm index 63e5d2396..98c742c48 100644 --- a/src/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm +++ b/src/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm @@ -196,13 +196,13 @@ Can be: 'node-usage', 'cpu-usage'. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm b/src/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm index 33fc163c6..ca0e77b78 100644 --- a/src/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm +++ b/src/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm @@ -336,13 +336,13 @@ Can be: 'node-idle', 'node-wait', 'node-interrupt', 'node-nice', =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/nodeexporter/mode/load.pm b/src/cloud/prometheus/exporters/nodeexporter/mode/load.pm index 8cb100916..471dddefe 100644 --- a/src/cloud/prometheus/exporters/nodeexporter/mode/load.pm +++ b/src/cloud/prometheus/exporters/nodeexporter/mode/load.pm @@ -171,13 +171,13 @@ Can be: 'load1', 'load5', 'load15'. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/nodeexporter/mode/memory.pm b/src/cloud/prometheus/exporters/nodeexporter/mode/memory.pm index 0fb3f2585..18072587c 100644 --- a/src/cloud/prometheus/exporters/nodeexporter/mode/memory.pm +++ b/src/cloud/prometheus/exporters/nodeexporter/mode/memory.pm @@ -241,13 +241,13 @@ Units of thresholds (Default: '%') ('%', 'B'). =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/exporters/nodeexporter/mode/storage.pm b/src/cloud/prometheus/exporters/nodeexporter/mode/storage.pm index 7cfbc1fc8..a37a16480 100644 --- a/src/cloud/prometheus/exporters/nodeexporter/mode/storage.pm +++ b/src/cloud/prometheus/exporters/nodeexporter/mode/storage.pm @@ -277,13 +277,13 @@ Threshold critical. =item B<--extra-filter> -Add a PromQL filter (Can be multiple) +Add a PromQL filter (can be defined multiple times) Example : --extra-filter='name=~".*pretty.*"' =item B<--metric-overload> -Overload default metrics name (Can be multiple) +Overload default metrics name (can be defined multiple times) Example : --metric-overload='metric,^my_metric_name$' diff --git a/src/cloud/prometheus/restapi/mode/targetstatus.pm b/src/cloud/prometheus/restapi/mode/targetstatus.pm index dbc3a9161..d8c920ff4 100644 --- a/src/cloud/prometheus/restapi/mode/targetstatus.pm +++ b/src/cloud/prometheus/restapi/mode/targetstatus.pm @@ -202,17 +202,17 @@ Check targets status. =item B<--filter-label> -Set filter on label (Regexp, Can be multiple) (Example: --filter-label='job,kube.*'). +Set filter on label (Regexp, can be defined multiple times) (Example: --filter-label='job,kube.*'). =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{display}, %{health}. +You can use the following variables: %{display}, %{health}. =item B<--critical-status> Set critical threshold for status (Default: '%{health} !~ /up/'). -Can used special variables like: %{display}, %{health} +You can use the following variables: %{display}, %{health} =item B<--warning-*> diff --git a/src/cloud/talend/tmc/mode/plans.pm b/src/cloud/talend/tmc/mode/plans.pm index d58ba59fe..4c58cf678 100644 --- a/src/cloud/talend/tmc/mode/plans.pm +++ b/src/cloud/talend/tmc/mode/plans.pm @@ -365,17 +365,17 @@ Select the unit for last execution time threshold. May be 's' for seconds, 'm' f =item B<--unknown-execution-status> Set unknown threshold for last plan execution status. -Can used special variables like: %{status}, %{planName} +You can use the following variables: %{status}, %{planName} =item B<--warning-execution-status> Set warning threshold for last plan execution status. -Can used special variables like: %{status}, %{planName} +You can use the following variables: %{status}, %{planName} =item B<--critical-execution-status> Set critical threshold for last plan execution status (Default: '{status} =~ /execution_failed/i'). -Can used special variables like: %{status}, %{planName} +You can use the following variables: %{status}, %{planName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/talend/tmc/mode/remoteengines.pm b/src/cloud/talend/tmc/mode/remoteengines.pm index 927c106cf..cdb152a63 100644 --- a/src/cloud/talend/tmc/mode/remoteengines.pm +++ b/src/cloud/talend/tmc/mode/remoteengines.pm @@ -156,17 +156,17 @@ Environment filter (Can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{availability}, %{name} +You can use the following variables: %{status}, %{availability}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{availability}, %{name} +You can use the following variables: %{status}, %{availability}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{availability} !~ /retired/ and %{status} =~ /unpaired/i'). -Can used special variables like: %{status}, %{availability}, %{name} +You can use the following variables: %{status}, %{availability}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/talend/tmc/mode/tasks.pm b/src/cloud/talend/tmc/mode/tasks.pm index 2f8ae6c5b..48148903f 100644 --- a/src/cloud/talend/tmc/mode/tasks.pm +++ b/src/cloud/talend/tmc/mode/tasks.pm @@ -365,17 +365,17 @@ Select the unit for last execution time threshold. May be 's' for seconds, 'm' f =item B<--unknown-execution-status> Set unknown threshold for last task execution status. -Can used special variables like: %{status}, %{taskName} +You can use the following variables: %{status}, %{taskName} =item B<--warning-execution-status> Set warning threshold for last task execution status. -Can used special variables like: %{status}, %{taskName} +You can use the following variables: %{status}, %{taskName} =item B<--critical-execution-status> Set critical threshold for last task execution status (Default: %{status} =~ /deploy_failed|execution_rejected|execution_failed|terminated_timeout/i). -Can used special variables like: %{status}, %{taskName} +You can use the following variables: %{status}, %{taskName} =item B<--warning-*> B<--critical-*> diff --git a/src/cloud/vmware/velocloud/restapi/mode/edgestatus.pm b/src/cloud/vmware/velocloud/restapi/mode/edgestatus.pm index 82d3ee67d..bcc8c6cf6 100644 --- a/src/cloud/vmware/velocloud/restapi/mode/edgestatus.pm +++ b/src/cloud/vmware/velocloud/restapi/mode/edgestatus.pm @@ -128,19 +128,19 @@ Filter edge by name (Can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{edge_state} =~ /NEVER_ACTIVATED/'). -Can used special variables like: %{edge_state}, %{service_state}, +You can use the following variables: %{edge_state}, %{service_state}, %{ha_state}, %{activation_state}. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{edge_state}, %{service_state}, +You can use the following variables: %{edge_state}, %{service_state}, %{ha_state}, %{activation_state}. =item B<--critical-status> Set critical threshold for status (Default: '%{edge_state} !~ /CONNECTED/ && %{edge_state} !~ /NEVER_ACTIVATED/'). -Can used special variables like: %{edge_state}, %{service_state}, +You can use the following variables: %{edge_state}, %{service_state}, %{ha_state}, %{activation_state}. =back diff --git a/src/cloud/vmware/velocloud/restapi/mode/linkstatus.pm b/src/cloud/vmware/velocloud/restapi/mode/linkstatus.pm index 80966e52f..cd5b9193e 100644 --- a/src/cloud/vmware/velocloud/restapi/mode/linkstatus.pm +++ b/src/cloud/vmware/velocloud/restapi/mode/linkstatus.pm @@ -182,7 +182,7 @@ Filter link by name (Can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{vpn_state}, %{backup_state}. +You can use the following variables: %{state}, %{vpn_state}, %{backup_state}. =item B<--warning-*> B<--critical-*> diff --git a/src/database/couchdb/restapi/mode/server.pm b/src/database/couchdb/restapi/mode/server.pm index 8200b73d9..ff1235c7c 100644 --- a/src/database/couchdb/restapi/mode/server.pm +++ b/src/database/couchdb/restapi/mode/server.pm @@ -210,32 +210,32 @@ Filter database name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^ok/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-compaction-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{compaction_status}, %{display} +You can use the following variables: %{compaction_status}, %{display} =item B<--warning-compaction-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{compaction_status}, %{display} +You can use the following variables: %{compaction_status}, %{display} =item B<--critical-compaction-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{compaction_status}, %{display} +You can use the following variables: %{compaction_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/database/db2/mode/hadr.pm b/src/database/db2/mode/hadr.pm index a110677d7..d367846ea 100644 --- a/src/database/db2/mode/hadr.pm +++ b/src/database/db2/mode/hadr.pm @@ -216,47 +216,47 @@ Check high availability disaster recovery. =item B<--unknown-connection-status> Set unknown threshold for connection status. -Can used special variables like: %{status}, %{primaryMember}, %{standbyMember}, %{standbyId} +You can use the following variables: %{status}, %{primaryMember}, %{standbyMember}, %{standbyId} =item B<--warning-connection-status> Set warning threshold for connection status (Default: '%{status} eq "congested"'). -Can used special variables like: %{status}, %{primaryMember}, %{standbyMember}, %{standbyId} +You can use the following variables: %{status}, %{primaryMember}, %{standbyMember}, %{standbyId} =item B<--critical-connection-status> Set critical threshold for connection status (Default: '%{status} eq "disconnected"'). -Can used special variables like: %{status}, %{primaryMember}, %{standbyMember}, %{standbyId} +You can use the following variables: %{status}, %{primaryMember}, %{standbyMember}, %{standbyId} =item B<--unknown-state> Set unknown threshold for state. -Can used special variables like: %{state}, %{primaryMember}, %{standbyMember}, %{standbyId} +You can use the following variables: %{state}, %{primaryMember}, %{standbyMember}, %{standbyId} =item B<--warning-state> Set warning threshold for state. -Can used special variables like: %{state}, %{primaryMember}, %{standbyMember}, %{standbyId} +You can use the following variables: %{state}, %{primaryMember}, %{standbyMember}, %{standbyId} =item B<--critical-state> Set critical threshold for state (Default: '%{state} ne "peer"'). -Can used special variables like: %{state}, %{primaryMember}, %{standbyMember}, %{standbyId} +You can use the following variables: %{state}, %{primaryMember}, %{standbyMember}, %{standbyId} =item B<--unknown-role> Set unknown threshold for role status. -Can used special variables like: %{role}, %{roleLast}, %{primaryMember}, %{primaryMemberLast}, %{standbyMember}, %{standbyMemberLast}, %{standbyId} +You can use the following variables: %{role}, %{roleLast}, %{primaryMember}, %{primaryMemberLast}, %{standbyMember}, %{standbyMemberLast}, %{standbyId} =item B<--warning-role> Set warning threshold for role status. -Can used special variables like: %{role}, %{roleLast}, %{primaryMember}, %{primaryMemberLast}, %{standbyMember}, %{standbyMemberLast}, %{standbyId} +You can use the following variables: %{role}, %{roleLast}, %{primaryMember}, %{primaryMemberLast}, %{standbyMember}, %{standbyMemberLast}, %{standbyId} =item B<--critical-role> Set critical threshold for role status. -Can used special variables like: %{role}, %{roleLast}, %{primaryMember}, %{primaryMemberLast}, %{standbyMember}, %{standbyMemberLast}, %{standbyId} +You can use the following variables: %{role}, %{roleLast}, %{primaryMember}, %{primaryMemberLast}, %{standbyMember}, %{standbyMemberLast}, %{standbyId} =item B<--warning-*> B<--critical-*> diff --git a/src/database/db2/mode/tablespaces.pm b/src/database/db2/mode/tablespaces.pm index 5177911fa..eafa55045 100644 --- a/src/database/db2/mode/tablespaces.pm +++ b/src/database/db2/mode/tablespaces.pm @@ -291,17 +291,17 @@ Filter tablespaces by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{tbsname}, %{type}, %{state} +You can use the following variables: %{tbsname}, %{type}, %{state} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{tbsname}, %{type}, %{state} +You can use the following variables: %{tbsname}, %{type}, %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /normal/i'). -Can used special variables like: %{tbsname}, %{type}, %{state} +You can use the following variables: %{tbsname}, %{type}, %{state} =item B<--warning-*> B<--critical-*> diff --git a/src/database/elasticsearch/restapi/mode/clusterstatistics.pm b/src/database/elasticsearch/restapi/mode/clusterstatistics.pm index a2b5f55e9..8d4d2e164 100644 --- a/src/database/elasticsearch/restapi/mode/clusterstatistics.pm +++ b/src/database/elasticsearch/restapi/mode/clusterstatistics.pm @@ -279,12 +279,12 @@ Can be: 'nodes-total', 'nodes-data', 'nodes-coordinating', =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /yellow/i') -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /red/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =back diff --git a/src/database/elasticsearch/restapi/mode/indicestatistics.pm b/src/database/elasticsearch/restapi/mode/indicestatistics.pm index 53e1d7be8..7e0f301d7 100644 --- a/src/database/elasticsearch/restapi/mode/indicestatistics.pm +++ b/src/database/elasticsearch/restapi/mode/indicestatistics.pm @@ -199,12 +199,12 @@ Can be: 'documents-total', 'data-size-primaries', =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /yellow/i') -Can used special variables like: %{display}, %{status}. +You can use the following variables: %{display}, %{status}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /red/i'). -Can used special variables like: %{display}, %{status}. +You can use the following variables: %{display}, %{status}. =back diff --git a/src/database/elasticsearch/restapi/mode/license.pm b/src/database/elasticsearch/restapi/mode/license.pm index 1aa9b224c..83aaccac1 100644 --- a/src/database/elasticsearch/restapi/mode/license.pm +++ b/src/database/elasticsearch/restapi/mode/license.pm @@ -97,12 +97,12 @@ Check license. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{type}, %{issued_to}, %{expiry_date_in_seconds}. +You can use the following variables: %{status}, %{type}, %{issued_to}, %{expiry_date_in_seconds}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /active/i'). -Can used special variables like: %{status}, %{type}, %{issued_to}, %{expiry_date_in_seconds}. +You can use the following variables: %{status}, %{type}, %{issued_to}, %{expiry_date_in_seconds}. =back diff --git a/src/database/informix/snmp/mode/chunkstatus.pm b/src/database/informix/snmp/mode/chunkstatus.pm index 39440a730..1d4104c30 100644 --- a/src/database/informix/snmp/mode/chunkstatus.pm +++ b/src/database/informix/snmp/mode/chunkstatus.pm @@ -158,17 +158,17 @@ Filter chunk name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /inconsistent/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/database/mongodb/mode/replicationstatus.pm b/src/database/mongodb/mode/replicationstatus.pm index 7937fe106..fbebdb1f2 100644 --- a/src/database/mongodb/mode/replicationstatus.pm +++ b/src/database/mongodb/mode/replicationstatus.pm @@ -216,23 +216,23 @@ Check replication status =item B<--warning-status> Set warning threshold for checked instance status (Default: ''). -Can used special variables like: %{state}, %{sync_host}. +You can use the following variables: %{state}, %{sync_host}. =item B<--critical-status> Set critical threshold for checked instance status (Default: ''). -Can used special variables like: %{state}, %{sync_host}. +You can use the following variables: %{state}, %{sync_host}. =item B<--warning-member-status> Set warning threshold for members status (Default: '%{state} !~ /PRIMARY|SECONDARY/'). -Can used special variables like: %{name}, %{state}, %{health}, +You can use the following variables: %{name}, %{state}, %{health}, %{slave_delay}, %{priority}. =item B<--critical-member-status> Set critical threshold for members status (Default: '%{health} !~ /up/'). -Can used special variables like: %{name}, %{state}, %{health}, +You can use the following variables: %{name}, %{state}, %{health}, %{slave_delay}, %{priority}. =item B<--warning-instance-replication-lag-seconds> diff --git a/src/database/mssql/mode/failedjobs.pm b/src/database/mssql/mode/failedjobs.pm index 9ef5bb840..95004611a 100644 --- a/src/database/mssql/mode/failedjobs.pm +++ b/src/database/mssql/mode/failedjobs.pm @@ -230,12 +230,12 @@ Display job duration time. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{status}, %{duration} +You can use the following variables: %{name}, %{status}, %{duration} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{name}, %{status}, %{duration} +You can use the following variables: %{name}, %{status}, %{duration} =item B<--warning-*> B<--critical-*> diff --git a/src/database/mysql/mode/backup.pm b/src/database/mysql/mode/backup.pm index a109cbc97..2c3d05c45 100644 --- a/src/database/mysql/mode/backup.pm +++ b/src/database/mysql/mode/backup.pm @@ -158,17 +158,17 @@ Filter backups by type (regexp can be used). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{has_backup}, %{last_error}, %{exit_state}, %{type} +You can use the following variables: %{has_backup}, %{last_error}, %{exit_state}, %{type} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{has_backup}, %{last_error}, %{exit_state}, %{type} +You can use the following variables: %{has_backup}, %{last_error}, %{exit_state}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{has_backup} eq "yes" and %{exit_state} ne "SUCCESS" and %{last_error} ne "NO_ERROR"'). -Can used special variables like: %{has_backup}, %{last_error}, %{exit_state}, %{type} +You can use the following variables: %{has_backup}, %{last_error}, %{exit_state}, %{type} =item B<--warning-*> B<--critical-*> diff --git a/src/database/mysql/mode/passwordexpiration.pm b/src/database/mysql/mode/passwordexpiration.pm index e30952b1f..64a896ce1 100644 --- a/src/database/mysql/mode/passwordexpiration.pm +++ b/src/database/mysql/mode/passwordexpiration.pm @@ -211,12 +211,12 @@ Check user password expiration. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{user}, %{expire}, %{expire_time} +You can use the following variables: %{user}, %{expire}, %{expire_time} =item B<--critical-status> Set critical threshold for status (Default: '%{expire} ne "never" and %{expire_time} == 0'). -Can used special variables like: %{user}, %{expire}, %{expire_time} +You can use the following variables: %{user}, %{expire}, %{expire_time} =back diff --git a/src/database/mysql/mode/replication.pm b/src/database/mysql/mode/replication.pm index 07463bc84..70eed291e 100644 --- a/src/database/mysql/mode/replication.pm +++ b/src/database/mysql/mode/replication.pm @@ -368,32 +368,32 @@ Check MySQL replication (need to use --multiple). =item B<--unknown-connection-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{error_message}, %{display} +You can use the following variables: %{status}, %{error_message}, %{display} =item B<--warning-connection-status> Set warning threshold for status. -Can used special variables like: %{status}, %{error_message}, %{display} +You can use the following variables: %{status}, %{error_message}, %{display} =item B<--critical-connection-status> Set critical threshold for status (Default: '%{status} ne "ok"'). -Can used special variables like: %{status}, %{error_message}, %{display} +You can use the following variables: %{status}, %{error_message}, %{display} =item B<--unknown-replication-status> Set unknown threshold for status (Default: '%{replication_status} =~ /configurationIssue/i'). -Can used special variables like: %{replication_status}, %{display} +You can use the following variables: %{replication_status}, %{display} =item B<--warning-replication-status> Set warning threshold for status (Default: '%{replication_status} =~ /inProgress/i'). -Can used special variables like: %{replication_status}, %{display} +You can use the following variables: %{replication_status}, %{display} =item B<--critical-replication-status> Set critical threshold for status (Default: '%{replication_status} =~ /connectIssueToMaster/i'). -Can used special variables like: %{replication_status}, %{display} +You can use the following variables: %{replication_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/database/oracle/mode/asmdiskgroupusage.pm b/src/database/oracle/mode/asmdiskgroupusage.pm index 87089141b..cf4c65b73 100644 --- a/src/database/oracle/mode/asmdiskgroupusage.pm +++ b/src/database/oracle/mode/asmdiskgroupusage.pm @@ -266,27 +266,27 @@ Threshold critical. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-offline-disks> Set warning threshold for offline disks (Default: '(%{offline_disks} > 0 && %{type} eq "extern") || (%{offline_disks} > 1 && %{type} eq "high")'). -Can used special variables like: %{offline_disks}, %{type}, %{display} +You can use the following variables: %{offline_disks}, %{type}, %{display} =item B<--critical-offline-disks> Set critical threshold for offline disks (Default: '%{offline_disks} > 0 && %{type} =~ /^normal|high$/'). -Can used special variables like: %{offline_disks}, %{type}, %{display} +You can use the following variables: %{offline_disks}, %{type}, %{display} =item B<--units> diff --git a/src/database/oracle/mode/datafilesstatus.pm b/src/database/oracle/mode/datafilesstatus.pm index 71f686576..c2ed0b71d 100644 --- a/src/database/oracle/mode/datafilesstatus.pm +++ b/src/database/oracle/mode/datafilesstatus.pm @@ -246,22 +246,22 @@ Filter data file name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: none). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /offline|invalid/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--warning-online-status> Set warning threshold for online status (Default: '%{online_status} =~ /sysoff/i'). -Can used special variables like: %{display}, %{online_status} +You can use the following variables: %{display}, %{online_status} =item B<--critical-online-status> Set critical threshold for online status (Default: '%{online_status} =~ /offline|recover/i'). -Can used special variables like: %{display}, %{online_status} +You can use the following variables: %{display}, %{online_status} =item B<--warning-*> B<--critical-*> diff --git a/src/database/oracle/mode/dataguard.pm b/src/database/oracle/mode/dataguard.pm index 1c2d1c748..433d7bd94 100644 --- a/src/database/oracle/mode/dataguard.pm +++ b/src/database/oracle/mode/dataguard.pm @@ -193,17 +193,17 @@ Check oracle dataguard. =item B<--unknown-status> Set unknown threshold for status (Default: '%{mrp_status} =~ /undefined/ || %{log_transport} =~ /undefined/'). -Can used special variables like: %{roleLast}, %{role}, %{open_mode}, %{mrp_status}, %{mrp_process}, %{log_transport} +You can use the following variables: %{roleLast}, %{role}, %{open_mode}, %{mrp_status}, %{mrp_process}, %{log_transport} =item B<--warning-status> Set warning threshold for status (Default: '%{mrp_status} =~ /WAIT_FOR_LOG/i and %{log_transport} =~ /LGWR/i'). -Can used special variables like: %{roleLast}, %{role}, %{open_mode}, %{mrp_status}, %{mrp_process}, %{log_transport} +You can use the following variables: %{roleLast}, %{role}, %{open_mode}, %{mrp_status}, %{mrp_process}, %{log_transport} =item B<--critical-status> Set critical threshold for status (Default: '%{roleLast} ne %{role} || %{mrp_status} !~ /undefined|APPLYING_LOG|WAIT_FOR_LOG/i'). -Can used special variables like: %{roleLast}, %{role}, %{open_mode}, %{mrp_status}, %{mrp_process}, %{log_transport} +You can use the following variables: %{roleLast}, %{role}, %{open_mode}, %{mrp_status}, %{mrp_process}, %{log_transport} =item B<--warning-*> B<--critical-*> diff --git a/src/database/oracle/mode/longqueries.pm b/src/database/oracle/mode/longqueries.pm index c495699c9..1e31fbeaf 100644 --- a/src/database/oracle/mode/longqueries.pm +++ b/src/database/oracle/mode/longqueries.pm @@ -182,12 +182,12 @@ Check long sql queries. =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{username}, %{sql_text}, %{since}, %{status} +You can use the following variables: %{username}, %{sql_text}, %{since}, %{status} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{username}, %{sql_text}, %{since}, %{status} +You can use the following variables: %{username}, %{sql_text}, %{since}, %{status} =item B<--timezone> diff --git a/src/database/oracle/mode/passwordexpiration.pm b/src/database/oracle/mode/passwordexpiration.pm index 6f11b694c..16ffad410 100644 --- a/src/database/oracle/mode/passwordexpiration.pm +++ b/src/database/oracle/mode/passwordexpiration.pm @@ -149,12 +149,12 @@ Check user password expiration. =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{username}, %{account_status}, %{expire} +You can use the following variables: %{username}, %{account_status}, %{expire} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{username}, %{account_status}, %{expire} +You can use the following variables: %{username}, %{account_status}, %{expire} =item B<--timezone> diff --git a/src/database/redis/mode/persistence.pm b/src/database/redis/mode/persistence.pm index ca67a3215..ed3c92965 100644 --- a/src/database/redis/mode/persistence.pm +++ b/src/database/redis/mode/persistence.pm @@ -140,12 +140,12 @@ Check RDB persistence status. =item B<--warning-status> Set warning threshold for status (Default: '%{progress_status} =~ /in progress/i'). -Can used special variables like: %{progress_status}, %{status} +You can use the following variables: %{progress_status}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /fail/i'). -Can used special variables like: %{progress_status}, %{status} +You can use the following variables: %{progress_status}, %{status} =item B<--warning-*> diff --git a/src/database/redis/mode/replication.pm b/src/database/redis/mode/replication.pm index ff5add049..c953d76b5 100644 --- a/src/database/redis/mode/replication.pm +++ b/src/database/redis/mode/replication.pm @@ -172,12 +172,12 @@ Check replication status. =item B<--warning-status> Set warning threshold for status (Default: '%{sync_status} =~ /in progress/i'). -Can used special variables like: %{sync_status}, %{link_status}, %{cluster_state} +You can use the following variables: %{sync_status}, %{link_status}, %{cluster_state} =item B<--critical-status> Set critical threshold for status (Default: '%{link_status} =~ /down/i'). -Can used special variables like: %{sync_status}, %{link_status}, %{cluster_state} +You can use the following variables: %{sync_status}, %{link_status}, %{cluster_state} =item B<--warning-*> diff --git a/src/hardware/ats/apc/snmp/mode/outputlines.pm b/src/hardware/ats/apc/snmp/mode/outputlines.pm index 92dbaa7ba..5162c5078 100644 --- a/src/hardware/ats/apc/snmp/mode/outputlines.pm +++ b/src/hardware/ats/apc/snmp/mode/outputlines.pm @@ -199,12 +199,12 @@ Can be: 'voltage', 'current', 'power', 'load', 'load-capacity'. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /nearoverload/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^(lowload|overload)$/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/hardware/ats/eaton/snmp/mode/system.pm b/src/hardware/ats/eaton/snmp/mode/system.pm index ca9b7af72..c5a5a53d1 100644 --- a/src/hardware/ats/eaton/snmp/mode/system.pm +++ b/src/hardware/ats/eaton/snmp/mode/system.pm @@ -165,17 +165,17 @@ Example: --filter-counters='^status$' =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: operation_mode +You can use the following variables: operation_mode =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: operation_mode +You can use the following variables: operation_mode =item B<--critical-status> Set critical threshold for status (Default: '%{operation_mode} !~ /source1|source2/i'). -Can used special variables like: %{operation_mode} +You can use the following variables: %{operation_mode} =item B<--warning-*> diff --git a/src/hardware/devices/aeg/acm/snmp/mode/acstatus.pm b/src/hardware/devices/aeg/acm/snmp/mode/acstatus.pm index ec61e7818..8f3153b1e 100644 --- a/src/hardware/devices/aeg/acm/snmp/mode/acstatus.pm +++ b/src/hardware/devices/aeg/acm/snmp/mode/acstatus.pm @@ -133,12 +133,12 @@ Check AC plant status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /true/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm b/src/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm index 91da295c1..e49440b75 100644 --- a/src/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm +++ b/src/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm @@ -238,12 +238,12 @@ Example: --filter-counters='^status|current$' =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /onBattery/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /disconnected/i || %{status} =~ /shutdown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm b/src/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm index 3459941d4..ccc1c7f36 100644 --- a/src/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm +++ b/src/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm @@ -194,12 +194,12 @@ Example: --filter-counters='^status|current$' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /ok|notInstalled/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/hardware/devices/barco/cs/restapi/mode/device.pm b/src/hardware/devices/barco/cs/restapi/mode/device.pm index 6e60800ce..f1d15e64d 100644 --- a/src/hardware/devices/barco/cs/restapi/mode/device.pm +++ b/src/hardware/devices/barco/cs/restapi/mode/device.pm @@ -254,22 +254,22 @@ Example: --filter-counters='status' =item B<--warning-device-status> Set warning threshold (Default: '%{status} =~ /warning/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-device-status> Set critical threshold (Default: '%{status} =~ /error/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-process-status> Set warning threshold. -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-process-status> Set critical threshold. -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/cisco/ces/restapi/mode/diagnostics.pm b/src/hardware/devices/cisco/ces/restapi/mode/diagnostics.pm index 3e311b0e4..fc5b67348 100644 --- a/src/hardware/devices/cisco/ces/restapi/mode/diagnostics.pm +++ b/src/hardware/devices/cisco/ces/restapi/mode/diagnostics.pm @@ -151,12 +151,12 @@ Use old legacy command. =item B<--warning-status> Set warning threshold for status (Default: '%{level} =~ /warning|minor/i') -Can used special variables like: %{description}, %{level}, %{type} +You can use the following variables: %{description}, %{level}, %{type} =item B<--critical-status> Set critical threshold for status (Default: '%{level} =~ /critical|major/i'). -Can used special variables like: %{description}, %{level}, %{type} +You can use the following variables: %{description}, %{level}, %{type} =back diff --git a/src/hardware/devices/cisco/cts/snmp/mode/peripherals.pm b/src/hardware/devices/cisco/cts/snmp/mode/peripherals.pm index af98ae90a..689966895 100644 --- a/src/hardware/devices/cisco/cts/snmp/mode/peripherals.pm +++ b/src/hardware/devices/cisco/cts/snmp/mode/peripherals.pm @@ -145,12 +145,12 @@ Filter peripheral by description (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{description} +You can use the following variables: %{status}, %{description} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^registered/'). -Can used special variables like: %{status}, %{description} +You can use the following variables: %{status}, %{description} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/eltek/enexus/snmp/mode/alarms.pm b/src/hardware/devices/eltek/enexus/snmp/mode/alarms.pm index 7a2881360..08d24729c 100644 --- a/src/hardware/devices/eltek/enexus/snmp/mode/alarms.pm +++ b/src/hardware/devices/eltek/enexus/snmp/mode/alarms.pm @@ -153,17 +153,17 @@ Filter name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{lastOpError}, %{display} +You can use the following variables: %{state}, %{status}, %{lastOpError}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "alarm"). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/eltek/enexus/snmp/mode/battery.pm b/src/hardware/devices/eltek/enexus/snmp/mode/battery.pm index 23f5afe0d..74a81b648 100644 --- a/src/hardware/devices/eltek/enexus/snmp/mode/battery.pm +++ b/src/hardware/devices/eltek/enexus/snmp/mode/battery.pm @@ -301,17 +301,17 @@ Check battery. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /minor|warning/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error|major|critical/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/eltek/enexus/snmp/mode/load.pm b/src/hardware/devices/eltek/enexus/snmp/mode/load.pm index 6f77ccd96..9d47fc6c8 100644 --- a/src/hardware/devices/eltek/enexus/snmp/mode/load.pm +++ b/src/hardware/devices/eltek/enexus/snmp/mode/load.pm @@ -198,17 +198,17 @@ Check load. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /minor|warning/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error|major|critical/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/eltek/enexus/snmp/mode/outputs.pm b/src/hardware/devices/eltek/enexus/snmp/mode/outputs.pm index 7f01c1940..80504f621 100644 --- a/src/hardware/devices/eltek/enexus/snmp/mode/outputs.pm +++ b/src/hardware/devices/eltek/enexus/snmp/mode/outputs.pm @@ -176,17 +176,17 @@ Filter name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /notenergized|disconnected/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm b/src/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm index 900015c60..23e965dad 100644 --- a/src/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm +++ b/src/hardware/devices/gorgy/ntpserver/snmp/mode/globalstatus.pm @@ -176,22 +176,22 @@ Example: --filter-counters='^sync-status$' =item B<--warning-sync-status> Set warning threshold for status (Default: '%{sync_status} =~ /Running with autonomy|Free running/i'). -Can used special variables like: %{sync_status} +You can use the following variables: %{sync_status} =item B<--critical-sync-status> Set critical threshold for status (Default: '%{sync_status} =~ /Server locked|Never synchronized|Server not synchronized/i'). -Can used special variables like: %{sync_status} +You can use the following variables: %{sync_status} =item B<--warning-timebase-status> Set warning threshold for status (Default: '%{timebase_status} =~ /^(?!(XO|XO OK|TCXO Precision < 2usec|OCXO Precision < 1usec)$)/i'). -Can used special variables like: %{timebase_status} +You can use the following variables: %{timebase_status} =item B<--critical-timebase-status> Set critical threshold for status (Default: '%{timebase_status} =~ /^XO$/i'). -Can used special variables like: %{timebase_status} +You can use the following variables: %{timebase_status} =item B<--warning-*> diff --git a/src/hardware/devices/hikvision/nvr/isapi/mode/disks.pm b/src/hardware/devices/hikvision/nvr/isapi/mode/disks.pm index 90e75b34c..3d73e6035 100644 --- a/src/hardware/devices/hikvision/nvr/isapi/mode/disks.pm +++ b/src/hardware/devices/hikvision/nvr/isapi/mode/disks.pm @@ -191,17 +191,17 @@ Filter disks by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /reparing/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error|smartFailed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm b/src/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm index 0b700a6d5..52b0635a3 100644 --- a/src/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm +++ b/src/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm @@ -109,17 +109,17 @@ Filter protocols by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{enabled}, %{name} +You can use the following variables: %{enabled}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{enabled}, %{name} +You can use the following variables: %{enabled}, %{name} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{enabled}, %{name} +You can use the following variables: %{enabled}, %{name} =back =cut diff --git a/src/hardware/devices/hikvision/nvr/snmp/mode/disks.pm b/src/hardware/devices/hikvision/nvr/snmp/mode/disks.pm index b79c24058..df02f5477 100644 --- a/src/hardware/devices/hikvision/nvr/snmp/mode/disks.pm +++ b/src/hardware/devices/hikvision/nvr/snmp/mode/disks.pm @@ -208,17 +208,17 @@ Filter disks by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning--status> Set warning threshold for status (Default: '%{status} =~ /reparing|formatting/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /abnormal|smartfailed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/hms/ewon/snmp/mode/tags.pm b/src/hardware/devices/hms/ewon/snmp/mode/tags.pm index 7e94b82b6..b3ada4026 100644 --- a/src/hardware/devices/hms/ewon/snmp/mode/tags.pm +++ b/src/hardware/devices/hms/ewon/snmp/mode/tags.pm @@ -301,12 +301,12 @@ E.g: --tag-threshold-warning='tagNameMatch,50' --tag-threshold-critical='tagName =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /alarm/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/masterclock/ntp100gps/snmp/mode/gpsstatus.pm b/src/hardware/devices/masterclock/ntp100gps/snmp/mode/gpsstatus.pm index 1760add95..619ce93f5 100644 --- a/src/hardware/devices/masterclock/ntp100gps/snmp/mode/gpsstatus.pm +++ b/src/hardware/devices/masterclock/ntp100gps/snmp/mode/gpsstatus.pm @@ -120,12 +120,12 @@ Check GPS status =item B<--warning-status> Set warning threshold for status (Default: '%{satellites} =~ /No satellites in view/') -Can used special variables like: %{health}, %{satellites}, %{latitude}, %{longitude} +You can use the following variables: %{health}, %{satellites}, %{latitude}, %{longitude} =item B<--critical-status> Set critical threshold for status (Default: '') -Can used special variables like: %{health}, %{satellites}, %{latitude}, %{longitude} +You can use the following variables: %{health}, %{satellites}, %{latitude}, %{longitude} =back diff --git a/src/hardware/devices/masterclock/ntp100gps/snmp/mode/ntpperformance.pm b/src/hardware/devices/masterclock/ntp100gps/snmp/mode/ntpperformance.pm index be762d67c..583bce197 100644 --- a/src/hardware/devices/masterclock/ntp100gps/snmp/mode/ntpperformance.pm +++ b/src/hardware/devices/masterclock/ntp100gps/snmp/mode/ntpperformance.pm @@ -141,12 +141,12 @@ Check NTP performances =item B<--warning-status> Set warning threshold for status (Default: '%{health} !~ /No leap second today/') -Can used special variables like: %{leap} +You can use the following variables: %{leap} =item B<--critical-status> Set critical threshold for status (Default: '') -Can used special variables like: %{health} +You can use the following variables: %{health} =item B<--warning-*> diff --git a/src/hardware/devices/pexip/infinity/managementapi/mode/alarms.pm b/src/hardware/devices/pexip/infinity/managementapi/mode/alarms.pm index c26277872..ea707784d 100644 --- a/src/hardware/devices/pexip/infinity/managementapi/mode/alarms.pm +++ b/src/hardware/devices/pexip/infinity/managementapi/mode/alarms.pm @@ -155,12 +155,12 @@ Filter by alert name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{level} =~ /warning|minor/i') -Can used special variables like: %{level}, %{details}, %{name} +You can use the following variables: %{level}, %{details}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{level} =~ /critical|major|error/i'). -Can used special variables like: %{level}, %{details}, %{name} +You can use the following variables: %{level}, %{details}, %{name} =item B<--memory> diff --git a/src/hardware/devices/polycom/trio/restapi/mode/device.pm b/src/hardware/devices/polycom/trio/restapi/mode/device.pm index d7fefa9d6..162f7a65b 100644 --- a/src/hardware/devices/polycom/trio/restapi/mode/device.pm +++ b/src/hardware/devices/polycom/trio/restapi/mode/device.pm @@ -149,12 +149,12 @@ Check device cpu, memory and state. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/devices/polycom/trio/restapi/mode/registration.pm b/src/hardware/devices/polycom/trio/restapi/mode/registration.pm index b736f418b..b68241bb9 100644 --- a/src/hardware/devices/polycom/trio/restapi/mode/registration.pm +++ b/src/hardware/devices/polycom/trio/restapi/mode/registration.pm @@ -91,12 +91,12 @@ Check SIP registration. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /registred/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/antenna.pm b/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/antenna.pm index 786fd1346..b02dc5875 100644 --- a/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/antenna.pm +++ b/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/antenna.pm @@ -103,17 +103,17 @@ Check antenna. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /shorted/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /notConnected/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/gnss.pm b/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/gnss.pm index d762e6c4c..6a447dabc 100644 --- a/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/gnss.pm +++ b/src/hardware/devices/timelinkmicro/tms6001/snmp/mode/gnss.pm @@ -97,17 +97,17 @@ Check GNSS. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /nominal/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/hardware/devices/video/appeartv/snmp/mode/alarms.pm b/src/hardware/devices/video/appeartv/snmp/mode/alarms.pm index 7a72bed4d..385847daf 100644 --- a/src/hardware/devices/video/appeartv/snmp/mode/alarms.pm +++ b/src/hardware/devices/video/appeartv/snmp/mode/alarms.pm @@ -173,12 +173,12 @@ Filter by message (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--memory> diff --git a/src/hardware/kvm/adder/aim/snmp/mode/deviceusage.pm b/src/hardware/kvm/adder/aim/snmp/mode/deviceusage.pm index 5e8d653cb..b97a54c63 100644 --- a/src/hardware/kvm/adder/aim/snmp/mode/deviceusage.pm +++ b/src/hardware/kvm/adder/aim/snmp/mode/deviceusage.pm @@ -173,12 +173,12 @@ Filter by device name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: 'not %{status} =~ /online|rebooting|upgrading/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/hardware/kvm/avocent/acs/8000/snmp/mode/serialports.pm b/src/hardware/kvm/avocent/acs/8000/snmp/mode/serialports.pm index b5745789b..99daeadc4 100644 --- a/src/hardware/kvm/avocent/acs/8000/snmp/mode/serialports.pm +++ b/src/hardware/kvm/avocent/acs/8000/snmp/mode/serialports.pm @@ -172,17 +172,17 @@ Filter by serial device name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/pdu/apc/snmp/mode/load.pm b/src/hardware/pdu/apc/snmp/mode/load.pm index 03c056ef1..be9181c76 100644 --- a/src/hardware/pdu/apc/snmp/mode/load.pm +++ b/src/hardware/pdu/apc/snmp/mode/load.pm @@ -290,32 +290,32 @@ Check phase/bank load. =item B<--unknown-bank-status> Set warning threshold for status. -Can used special variables like: %{type}, %{status}, %{display} +You can use the following variables: %{type}, %{status}, %{display} =item B<--warning-bank-status> Set warning threshold for status (Default: '%{status} =~ /low|nearOverload/i'). -Can used special variables like: %{type}, %{status}, %{display} +You can use the following variables: %{type}, %{status}, %{display} =item B<--critical-bank-status> Set critical threshold for status (Default: '%{status} =~ /^overload/'). -Can used special variables like: %{type}, %{status}, %{display} +You can use the following variables: %{type}, %{status}, %{display} =item B<--unknown-phase-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-phase-status> Set warning threshold for status (Default: '%{status} =~ /low|nearOverload/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-phase-status> Set critical threshold for status (Default: '%{status} =~ /^overload/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/pdu/apc/snmp/mode/outlet.pm b/src/hardware/pdu/apc/snmp/mode/outlet.pm index bb4b88c1b..b1ba1e898 100644 --- a/src/hardware/pdu/apc/snmp/mode/outlet.pm +++ b/src/hardware/pdu/apc/snmp/mode/outlet.pm @@ -245,17 +245,17 @@ Check outlet. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{phase}, %{bank}, %{display} +You can use the following variables: %{status}, %{phase}, %{bank}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /off/'). -Can used special variables like: %{status}, %{phase}, %{bank}, %{display} +You can use the following variables: %{status}, %{phase}, %{bank}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/pdu/cyberpower/snmp/mode/load.pm b/src/hardware/pdu/cyberpower/snmp/mode/load.pm index 6702b800b..8ee80e52f 100644 --- a/src/hardware/pdu/cyberpower/snmp/mode/load.pm +++ b/src/hardware/pdu/cyberpower/snmp/mode/load.pm @@ -287,32 +287,32 @@ Check phase/bank load. =item B<--unknown-bank-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-bank-status> Set warning threshold for status (Default: '%{state} =~ /low|nearOverload/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-bank-status> Set critical threshold for status (Default: '%{state} =~ /^overload/'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--unknown-phase-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-phase-status> Set warning threshold for status (Default: '%{state} =~ /low|nearOverload/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-phase-status> Set critical threshold for status (Default: '%{state} =~ /^overload/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/pdu/cyberpower/snmp/mode/outlets.pm b/src/hardware/pdu/cyberpower/snmp/mode/outlets.pm index 43ced5bc1..cce57f30f 100644 --- a/src/hardware/pdu/cyberpower/snmp/mode/outlets.pm +++ b/src/hardware/pdu/cyberpower/snmp/mode/outlets.pm @@ -285,17 +285,17 @@ Check outlets. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %%{state}, %{phase}, %{bank}, %{display} +You can use the following variables: %%{state}, %{phase}, %{bank}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{phase}, %{bank}, %{display} +You can use the following variables: %{state}, %{phase}, %{bank}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /off/'). -Can used special variables like: %{state}, %{phase}, %{bank}, %{display} +You can use the following variables: %{state}, %{phase}, %{bank}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/pdu/eaton/snmp/mode/environment.pm b/src/hardware/pdu/eaton/snmp/mode/environment.pm index d1217d5b1..678f1a1bf 100644 --- a/src/hardware/pdu/eaton/snmp/mode/environment.pm +++ b/src/hardware/pdu/eaton/snmp/mode/environment.pm @@ -233,32 +233,32 @@ Check pdu environmental sensors. =item B<--unknown-temperature-status> Set unknon threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-temperature-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-temperature-status> Set critical threshold for status (Default: '%{status} eq "bad"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--unknown-humidity-status> Set unknon threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-humidity-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-humidity-status> Set critical threshold for status (Default: '%{status} eq "bad"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/pdu/emerson/snmp/mode/globalstatus.pm b/src/hardware/pdu/emerson/snmp/mode/globalstatus.pm index 381528c2a..4db44b194 100644 --- a/src/hardware/pdu/emerson/snmp/mode/globalstatus.pm +++ b/src/hardware/pdu/emerson/snmp/mode/globalstatus.pm @@ -136,7 +136,7 @@ sub manage_selection { } if (scalar(keys %{$self->{pdu}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "Cannot found pdu."); + $self->{output}->add_option_msg(short_msg => "Cannot find pdu."); $self->{output}->option_exit(); } } @@ -158,12 +158,12 @@ Filter PDU name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /normalWithWarning/i'). -Can used special variables like: %{status}, %{display}. +You can use the following variables: %{status}, %{display}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /normalWithAlarm|abnormalOperation/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/hardware/pdu/emerson/snmp/mode/psusage.pm b/src/hardware/pdu/emerson/snmp/mode/psusage.pm index dedd3e510..2be6f63e1 100644 --- a/src/hardware/pdu/emerson/snmp/mode/psusage.pm +++ b/src/hardware/pdu/emerson/snmp/mode/psusage.pm @@ -197,7 +197,7 @@ sub manage_selection { } if (scalar(keys %{$self->{ps}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "Cannot found power sources."); + $self->{output}->add_option_msg(short_msg => "Cannot find power sources."); $self->{output}->option_exit(); } } diff --git a/src/hardware/pdu/emerson/snmp/mode/receptacles.pm b/src/hardware/pdu/emerson/snmp/mode/receptacles.pm index 63fd0b6f2..83aadf183 100644 --- a/src/hardware/pdu/emerson/snmp/mode/receptacles.pm +++ b/src/hardware/pdu/emerson/snmp/mode/receptacles.pm @@ -255,17 +255,17 @@ Filter receptable branch name (can be a regexp). =item B<--unknown-rcp-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{oper_state}, %{power_state}, %{display} +You can use the following variables: %{oper_state}, %{power_state}, %{display} =item B<--warning-rcp-status> Set warning threshold for status (Default: '%{oper_state} =~ /warning|alarm/'). -Can used special variables like: %{oper_state}, %{power_state}, %{display} +You can use the following variables: %{oper_state}, %{power_state}, %{display} =item B<--critical-rcp-status> Set critical threshold for status (Default: '%{oper_state} =~ /abnormal/'). -Can used special variables like: %{oper_state}, %{power_state}, %{display} +You can use the following variables: %{oper_state}, %{power_state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/printers/standard/rfc3805/mode/coverstatus.pm b/src/hardware/printers/standard/rfc3805/mode/coverstatus.pm index 7e66cfb1a..18c59293f 100644 --- a/src/hardware/printers/standard/rfc3805/mode/coverstatus.pm +++ b/src/hardware/printers/standard/rfc3805/mode/coverstatus.pm @@ -111,17 +111,17 @@ Check covers of the printer. =item B<--unknown-status> Set unknown threshold for status (Default: '%%{status} =~ /other|unknown/'). -Can used special variables like: %{status}, %{description} +You can use the following variables: %{status}, %{description} =item B<--warning-status> Set warning threshold for status (Default: '%%{status} =~ /coverOpen|interlockOpen/'). -Can used special variables like: %{status}, %{description} +You can use the following variables: %{status}, %{description} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{description} +You can use the following variables: %{status}, %{description} =back diff --git a/src/hardware/server/cisco/ucs/snmp/mode/auditlogs.pm b/src/hardware/server/cisco/ucs/snmp/mode/auditlogs.pm index 83013477a..2447eb772 100644 --- a/src/hardware/server/cisco/ucs/snmp/mode/auditlogs.pm +++ b/src/hardware/server/cisco/ucs/snmp/mode/auditlogs.pm @@ -210,12 +210,12 @@ Check audit logs. =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/') -Can used special variables like: %{severity}, %{description}, %{dn} +You can use the following variables: %{severity}, %{description}, %{dn} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /major|critical/'). -Can used special variables like: %{severity}, %{description}, %{dn} +You can use the following variables: %{severity}, %{description}, %{dn} =item B<--memory> diff --git a/src/hardware/server/cisco/ucs/snmp/mode/faults.pm b/src/hardware/server/cisco/ucs/snmp/mode/faults.pm index 779076b9c..3c8659dc7 100644 --- a/src/hardware/server/cisco/ucs/snmp/mode/faults.pm +++ b/src/hardware/server/cisco/ucs/snmp/mode/faults.pm @@ -216,12 +216,12 @@ Check faults. =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/') -Can used special variables like: %{severity}, %{description}, %{dn} +You can use the following variables: %{severity}, %{description}, %{dn} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /major|critical/'). -Can used special variables like: %{severity}, %{description}, %{dn} +You can use the following variables: %{severity}, %{description}, %{dn} =item B<--memory> diff --git a/src/hardware/server/cisco/ucs/snmp/mode/mgmtentities.pm b/src/hardware/server/cisco/ucs/snmp/mode/mgmtentities.pm index 298189da6..83fd1f32e 100644 --- a/src/hardware/server/cisco/ucs/snmp/mode/mgmtentities.pm +++ b/src/hardware/server/cisco/ucs/snmp/mode/mgmtentities.pm @@ -151,17 +151,17 @@ Check management entities. =item B<--unknown-status> Set unknown threshold for status (Default: '%{role} =~ /unknown/ or %{status} eq "unknown" or %{services_status} eq "unknown"') -Can used special variables like: %{dn}, %{role}, %{services_status}, %{status} +You can use the following variables: %{dn}, %{role}, %{services_status}, %{status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{dn}, %{role}, %{services_status}, %{status} +You can use the following variables: %{dn}, %{role}, %{services_status}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{role} =~ /electionFailed|inapplicable/ or %{status} eq "down" or %{services_status} eq "down"'). -Can used special variables like: %{dn}, %{role}, %{services_status}, %{status} +You can use the following variables: %{dn}, %{role}, %{services_status}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/server/cisco/ucs/snmp/mode/serviceprofile.pm b/src/hardware/server/cisco/ucs/snmp/mode/serviceprofile.pm index 2ea17a6ed..38b72d785 100644 --- a/src/hardware/server/cisco/ucs/snmp/mode/serviceprofile.pm +++ b/src/hardware/server/cisco/ucs/snmp/mode/serviceprofile.pm @@ -152,12 +152,12 @@ Check service profiles. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{dn}, %{status} +You can use the following variables: %{dn}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "offline"'). -Can used special variables like: %{dn}, %{status} +You can use the following variables: %{dn}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm b/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm index bc87ee19d..669d5cdec 100644 --- a/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm +++ b/src/hardware/server/dell/idrac/snmp/mode/globalstatus.pm @@ -172,32 +172,32 @@ Check the overall status of iDrac card. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /nonCritical|other/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /critical|nonRecoverable/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-storage-status> Set warning threshold for status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-storage-status> Set warning threshold for status (Default: '%{status} =~ /nonCritical|other/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-storage-status> Set critical threshold for status (Default: '%{status} =~ /critical|nonRecoverable/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/hardware/server/dell/vxm/restapi/mode/chassis.pm b/src/hardware/server/dell/vxm/restapi/mode/chassis.pm index 8d64d2cb5..8df042435 100644 --- a/src/hardware/server/dell/vxm/restapi/mode/chassis.pm +++ b/src/hardware/server/dell/vxm/restapi/mode/chassis.pm @@ -171,32 +171,32 @@ Filter clusters by serial number (Can be a regexp). =item B<--unknown-chassis-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{chassisSn} +You can use the following variables: %{status}, %{chassisSn} =item B<--warning-chassis-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{status}, %{chassisSn} +You can use the following variables: %{status}, %{chassisSn} =item B<--critical-chassis-status> Set critical threshold for status (Default: '%{status} =~ /critical|error/i'). -Can used special variables like: %{status}, %{chassisSn} +You can use the following variables: %{status}, %{chassisSn} =item B<--unknown-psu-status> Set unknown threshold for power supply status. -Can used special variables like: %{status}, %{chassisSn}, %{psuName} +You can use the following variables: %{status}, %{chassisSn}, %{psuName} =item B<--warning-psu-status> Set warning threshold for power supply status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{status}, %{chassisSn}, %{psuName} +You can use the following variables: %{status}, %{chassisSn}, %{psuName} =item B<--critical-psu-status> Set critical threshold for power supply status (Default: '%{status} =~ /critical|error/i'). -Can used special variables like: %{status}, %{chassisSn}, %{psuName} +You can use the following variables: %{status}, %{chassisSn}, %{psuName} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/server/dell/vxm/restapi/mode/hosts.pm b/src/hardware/server/dell/vxm/restapi/mode/hosts.pm index 1fc446aa6..073a82a04 100644 --- a/src/hardware/server/dell/vxm/restapi/mode/hosts.pm +++ b/src/hardware/server/dell/vxm/restapi/mode/hosts.pm @@ -226,47 +226,47 @@ Filter hosts by name (Can be a regexp). =item B<--unknown-host-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name}, %{sn} +You can use the following variables: %{status}, %{name}, %{sn} =item B<--warning-host-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{status}, %{name}, %{sn} +You can use the following variables: %{status}, %{name}, %{sn} =item B<--critical-host-status> Set critical threshold for status (Default: '%{status} =~ /critical|error/i'). -Can used special variables like: %{status}, %{name}, %{sn} +You can use the following variables: %{status}, %{name}, %{sn} =item B<--unknown-nic-status> Set unknown threshold for nic status. -Can used special variables like: %{status}, %{mac}, %{slot} +You can use the following variables: %{status}, %{mac}, %{slot} =item B<--warning-nic-status> Set warning threshold for nic status. -Can used special variables like: %{status}, %{mac}, %{slot} +You can use the following variables: %{status}, %{mac}, %{slot} =item B<--critical-nic-status> Set critical threshold for nic status -Can used special variables like: %{status}, %{mac}, %{slot} +You can use the following variables: %{status}, %{mac}, %{slot} =item B<--unknown-disk-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{sn}, %{bay}, %{slot} +You can use the following variables: %{status}, %{sn}, %{bay}, %{slot} =item B<--warning-disk-status> Set warning threshold for status. -Can used special variables like: %{status}, %{sn}, %{bay}, %{slot} +You can use the following variables: %{status}, %{sn}, %{bay}, %{slot} =item B<--critical-disk-status> Set critical threshold for status (Default: '%{status} !~ /OK/i'). -Can used special variables like: %{status}, %{sn}, %{bay}, %{slot} +You can use the following variables: %{status}, %{sn}, %{bay}, %{slot} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm b/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm index 1e9961ce3..3dc3108d8 100644 --- a/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm +++ b/src/hardware/server/hp/oneview/restapi/mode/storagepools.pm @@ -173,17 +173,17 @@ Filter pool name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /critical/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/server/ibm/hmc/ssh/mode/ledstatus.pm b/src/hardware/server/ibm/hmc/ssh/mode/ledstatus.pm index 7508679d7..0917e5971 100644 --- a/src/hardware/server/ibm/hmc/ssh/mode/ledstatus.pm +++ b/src/hardware/server/ibm/hmc/ssh/mode/ledstatus.pm @@ -153,22 +153,22 @@ Format of names: systemname[:lparname] =item B<--warning-physical-status> Set warning threshold (Default: ''). -Can used special variables like: %{ledstate}, %{display} +You can use the following variables: %{ledstate}, %{display} =item B<--critical-physical-status> Set critical threshold (Default: '%{ledstate} =~ /on/'). -Can used special variables like: %{ledstate}, %{display} +You can use the following variables: %{ledstate}, %{display} =item B<--warning-virtuallpar-status> Set warning threshold (Default: ''). -Can used special variables like: %{ledstate}, %{display} +You can use the following variables: %{ledstate}, %{display} =item B<--critical-virtuallpar-status> Set critical threshold (Default: '%{ledstate} =~ /on/'). -Can used special variables like: %{ledstate}, %{display} +You can use the following variables: %{ledstate}, %{display} =back diff --git a/src/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm b/src/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm index 87e1c7527..9fed566df 100644 --- a/src/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm +++ b/src/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm @@ -159,12 +159,12 @@ Check alarms. =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning/i') -Can used special variables like: %{severity}, %{text}, %{since} +You can use the following variables: %{severity}, %{text}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /error/i'). -Can used special variables like: %{severity}, %{text}, %{since} +You can use the following variables: %{severity}, %{text}, %{since} =item B<--timezone> diff --git a/src/hardware/telephony/avaya/aes/snmp/mode/services.pm b/src/hardware/telephony/avaya/aes/snmp/mode/services.pm index b349f163f..8843b4bea 100644 --- a/src/hardware/telephony/avaya/aes/snmp/mode/services.pm +++ b/src/hardware/telephony/avaya/aes/snmp/mode/services.pm @@ -293,32 +293,32 @@ Filter service name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{state}, %{license_error}, %{display} +You can use the following variables: %{status}, %{state}, %{license_error}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{state}, %{license_error}, %{display} +You can use the following variables: %{status}, %{state}, %{license_error}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "running" or %{status} ne "online"'). -Can used special variables like: %{status}, %{state}, %{license_error}, %{display} +You can use the following variables: %{status}, %{state}, %{license_error}, %{display} =item B<--unknown-aep-status> Set unknown threshold for status. -Can used special variables like: %{link_state}, %{session_state}, %{display} +You can use the following variables: %{link_state}, %{session_state}, %{display} =item B<--warning-aep-status> Set warning threshold for status. -Can used special variables like: %{link_state}, %{session_state}, %{display} +You can use the following variables: %{link_state}, %{session_state}, %{display} =item B<--critical-aep-status> Set critical threshold for status (Default: '%{link_state} ne "online" or %{session_state} ne "online"'). -Can used special variables like: %{link_state}, %{session_state}, %{display} +You can use the following variables: %{link_state}, %{session_state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/telephony/avaya/cm/snmp/mode/trunks.pm b/src/hardware/telephony/avaya/cm/snmp/mode/trunks.pm index eeaeba713..022adcb1a 100644 --- a/src/hardware/telephony/avaya/cm/snmp/mode/trunks.pm +++ b/src/hardware/telephony/avaya/cm/snmp/mode/trunks.pm @@ -140,17 +140,17 @@ Filter signaling group instance (can be a regexp). =item B<--unknown-sig-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{far_node}, %{display} +You can use the following variables: %{state}, %{far_node}, %{display} =item B<--warning-sig-status> Set warning threshold for status. -Can used special variables like: %{state}, %{far_node}, %{display} +You can use the following variables: %{state}, %{far_node}, %{display} =item B<--critical-sig-status> Set critical threshold for status (Default: '%{state} =~ /out-of-service/'). -Can used special variables like: %{state}, %{far_node}, %{display} +You can use the following variables: %{state}, %{far_node}, %{display} =back diff --git a/src/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm b/src/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm index 2119e3627..0e7114cf5 100644 --- a/src/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm +++ b/src/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm @@ -121,17 +121,17 @@ Check controller status. =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{h248_link_status}, %{registration_state} +You can use the following variables: %{h248_link_status}, %{registration_state} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{h248_link_status}, %{registration_state} +You can use the following variables: %{h248_link_status}, %{registration_state} =item B<--critical-status> Set critical threshold for status (Default: '%{h248_link_status} =~ /down/i || %{registration_state} =~ /notRegistred/i'). -Can used special variables like: %{h248_link_status}, %{registration_state} +You can use the following variables: %{h248_link_status}, %{registration_state} =back diff --git a/src/hardware/ups/alpha/snmp/mode/batterystatus.pm b/src/hardware/ups/alpha/snmp/mode/batterystatus.pm index 566e2bc39..7ee13b2c9 100644 --- a/src/hardware/ups/alpha/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/alpha/snmp/mode/batterystatus.pm @@ -161,17 +161,17 @@ Example: --filter-counters='^status|load$' =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /batteryLow/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /batteryDepleted/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/hardware/ups/apc/snmp/mode/batterystatus.pm b/src/hardware/ups/apc/snmp/mode/batterystatus.pm index cf69138d4..352d0b0bf 100644 --- a/src/hardware/ups/apc/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/apc/snmp/mode/batterystatus.pm @@ -341,47 +341,47 @@ Example: --filter-counters='^status|load$' =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{replace} +You can use the following variables: %{status}, %{replace} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /batteryLow/i'). -Can used special variables like: %{status}, %{replace} +You can use the following variables: %{status}, %{replace} =item B<--critical-status> Set critical threshold for status (Default: '%{replace} =~ /yes/i'). -Can used special variables like: %{status}, %{replace} +You can use the following variables: %{status}, %{replace} =item B<--unknown-battery-pack-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-battery-pack-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-battery-pack-status> Set critical threshold for status (Default: '%{status} ne "OK"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-cartridge-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-cartridge-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-cartridge-status> Set critical threshold for status (Default: '%{status} ne "OK"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/apc/snmp/mode/inputlines.pm b/src/hardware/ups/apc/snmp/mode/inputlines.pm index f1761aea7..d6490f5d6 100644 --- a/src/hardware/ups/apc/snmp/mode/inputlines.pm +++ b/src/hardware/ups/apc/snmp/mode/inputlines.pm @@ -150,12 +150,12 @@ Example: --filter-counters='^frequence|voltage$' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{last_cause} +You can use the following variables: %{last_cause} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{last_cause} +You can use the following variables: %{last_cause} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/apc/snmp/mode/outputlines.pm b/src/hardware/ups/apc/snmp/mode/outputlines.pm index 6575dceec..bdb59bf12 100644 --- a/src/hardware/ups/apc/snmp/mode/outputlines.pm +++ b/src/hardware/ups/apc/snmp/mode/outputlines.pm @@ -167,17 +167,17 @@ Example: --filter-counters='^status|load$' =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /onLine|rebooting/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/hp/snmp/mode/batterystatus.pm b/src/hardware/ups/hp/snmp/mode/batterystatus.pm index fb96dd58c..d966d4451 100644 --- a/src/hardware/ups/hp/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/hp/snmp/mode/batterystatus.pm @@ -153,17 +153,17 @@ Example: --filter-counters='status|current' =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/hp/snmp/mode/outputlines.pm b/src/hardware/ups/hp/snmp/mode/outputlines.pm index efb9214d6..96403c71c 100644 --- a/src/hardware/ups/hp/snmp/mode/outputlines.pm +++ b/src/hardware/ups/hp/snmp/mode/outputlines.pm @@ -191,17 +191,17 @@ Check output lines metrics. =item B<--unknown-source> Set unknown threshold for status (Default: ''). -Can used special variables like: %{source}. +You can use the following variables: %{source}. =item B<--warning-source> Set warning threshold for status (Default: ''). -Can used special variables like: %{source}. +You can use the following variables: %{source}. =item B<--critical-source> Set critical threshold for status (Default: '%{source} !~ /normal/i'). -Can used special variables like: %{source}. +You can use the following variables: %{source}. =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/mge/snmp/mode/inputlines.pm b/src/hardware/ups/mge/snmp/mode/inputlines.pm index 312b32414..b595d5be6 100644 --- a/src/hardware/ups/mge/snmp/mode/inputlines.pm +++ b/src/hardware/ups/mge/snmp/mode/inputlines.pm @@ -199,12 +199,12 @@ Can be: 'frequence', 'voltage', 'current'. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{badstatus}, %{failcause} +You can use the following variables: %{badstatus}, %{failcause} =item B<--critical-status> Set critical threshold for status (Default: '%{badstatus} =~ /yes/'). -Can used special variables like: %{badstatus}, %{failcause} +You can use the following variables: %{badstatus}, %{failcause} =back diff --git a/src/hardware/ups/powerware/snmp/mode/batterystatus.pm b/src/hardware/ups/powerware/snmp/mode/batterystatus.pm index 5abf20e07..358a7e101 100644 --- a/src/hardware/ups/powerware/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/powerware/snmp/mode/batterystatus.pm @@ -153,17 +153,17 @@ Example: --filter-counters='status|current' =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /batteryDischarging/i'). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}. +You can use the following variables: %{status}. =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/riello/snmp/mode/battery.pm b/src/hardware/ups/riello/snmp/mode/battery.pm index 061d60482..bd21cf342 100644 --- a/src/hardware/ups/riello/snmp/mode/battery.pm +++ b/src/hardware/ups/riello/snmp/mode/battery.pm @@ -160,17 +160,17 @@ Check battery status and charge remaining. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /low/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /depleted/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/riello/snmp/mode/outputlines.pm b/src/hardware/ups/riello/snmp/mode/outputlines.pm index 0e1239d24..f24670482 100644 --- a/src/hardware/ups/riello/snmp/mode/outputlines.pm +++ b/src/hardware/ups/riello/snmp/mode/outputlines.pm @@ -166,17 +166,17 @@ Ignore counters equals to 0. =item B<--unknown-source-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-source-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-source-status> Set critical threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/socomec/netvision/snmp/mode/battery.pm b/src/hardware/ups/socomec/netvision/snmp/mode/battery.pm index c249a737c..fb2c06db5 100644 --- a/src/hardware/ups/socomec/netvision/snmp/mode/battery.pm +++ b/src/hardware/ups/socomec/netvision/snmp/mode/battery.pm @@ -184,17 +184,17 @@ Check battery status and charge remaining. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /low/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /depleted|failure/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/socomec/netvision/snmp/mode/outputlines.pm b/src/hardware/ups/socomec/netvision/snmp/mode/outputlines.pm index d32328ad2..92af18345 100644 --- a/src/hardware/ups/socomec/netvision/snmp/mode/outputlines.pm +++ b/src/hardware/ups/socomec/netvision/snmp/mode/outputlines.pm @@ -194,17 +194,17 @@ Ignore counters equals to 0. =item B<--unknown-source-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-source-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-source-status> Set critical threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm index 227b178a2..ed784045a 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/batterystatus.pm @@ -163,17 +163,17 @@ Check battery status and charge remaining. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /low/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /depleted/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm b/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm index ba26ae07f..7699d2f96 100644 --- a/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm +++ b/src/hardware/ups/standard/rfc1628/snmp/mode/outputsource.pm @@ -94,17 +94,17 @@ Check output source status. =item B<--unknown-source-status> Set unknown threshold for status (Default: '%{status} =~ /other/') -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-source-status> Set warning threshold for status (Default: '%{status} =~ /bypass|battery|booster|reducer/') -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-source-status> Set critical threshold for status (Default: '%{status} =~ /none/') -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/network/a10/ax/snmp/mode/vserverusage.pm b/src/network/a10/ax/snmp/mode/vserverusage.pm index 47fb03ed8..697f376dc 100644 --- a/src/network/a10/ax/snmp/mode/vserverusage.pm +++ b/src/network/a10/ax/snmp/mode/vserverusage.pm @@ -203,12 +203,12 @@ Check virtual server usage. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/acmepacket/snmp/mode/sipusage.pm b/src/network/acmepacket/snmp/mode/sipusage.pm index 613f9b7d4..06ebea235 100644 --- a/src/network/acmepacket/snmp/mode/sipusage.pm +++ b/src/network/acmepacket/snmp/mode/sipusage.pm @@ -170,12 +170,12 @@ Check SIP usage. =item B<--warning-status> Set warning threshold for status (Default: -). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /outOfService|constraintsViolation|inServiceTimedOut/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/network/acmepacket/snmp/mode/systemusage.pm b/src/network/acmepacket/snmp/mode/systemusage.pm index f6a371766..0b896f781 100644 --- a/src/network/acmepacket/snmp/mode/systemusage.pm +++ b/src/network/acmepacket/snmp/mode/systemusage.pm @@ -200,12 +200,12 @@ Example: --filter-counters='^memory-usage$' =item B<--warning-replication-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{replication_state} +You can use the following variables: %{replication_state} =item B<--critical-replication-status> Set critical threshold for status (Default: '%{replication_state} =~ /outOfService/i'). -Can used special variables like: %{replication_state} +You can use the following variables: %{replication_state} =item B<--warning-*> diff --git a/src/network/adva/fsp150/snmp/mode/alarms.pm b/src/network/adva/fsp150/snmp/mode/alarms.pm index 90ebd3b7e..2de5d3770 100644 --- a/src/network/adva/fsp150/snmp/mode/alarms.pm +++ b/src/network/adva/fsp150/snmp/mode/alarms.pm @@ -277,12 +277,12 @@ Check alarms. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{description}, %{object}, %{severity}, %{type}, %{label}, %{since} +You can use the following variables: %{description}, %{object}, %{severity}, %{type}, %{label}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} eq "serviceAffecting"'). -Can used special variables like: {description}, %{object}, %{severity}, %{type}, %{label}, %{since} +You can use the following variables: {description}, %{object}, %{severity}, %{type}, %{label}, %{since} =item B<--timezone> diff --git a/src/network/adva/fsp3000/snmp/mode/alarms.pm b/src/network/adva/fsp3000/snmp/mode/alarms.pm index 1733959e9..5fbf342cb 100644 --- a/src/network/adva/fsp3000/snmp/mode/alarms.pm +++ b/src/network/adva/fsp3000/snmp/mode/alarms.pm @@ -301,12 +301,12 @@ Check alarms. =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning|minor/i') -Can used special variables like: %{severity}, %{type}, %{label}, %{since} +You can use the following variables: %{severity}, %{type}, %{label}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). -Can used special variables like: %{severity}, %{type}, %{label}, %{since} +You can use the following variables: %{severity}, %{type}, %{label}, %{since} =item B<--timezone> diff --git a/src/network/adva/fsp3000/snmp/mode/interfaces.pm b/src/network/adva/fsp3000/snmp/mode/interfaces.pm index 3e5d63225..fecc74c92 100644 --- a/src/network/adva/fsp3000/snmp/mode/interfaces.pm +++ b/src/network/adva/fsp3000/snmp/mode/interfaces.pm @@ -323,12 +323,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/alcatel/isam/snmp/mode/hubsapusage.pm b/src/network/alcatel/isam/snmp/mode/hubsapusage.pm index 7ca67bc63..20b634f6f 100644 --- a/src/network/alcatel/isam/snmp/mode/hubsapusage.pm +++ b/src/network/alcatel/isam/snmp/mode/hubsapusage.pm @@ -451,12 +451,12 @@ Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). =item B<--warning-status> Set warning threshold for ib status. -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--critical-status> Set critical threshold for ib status (Default: '%{admin} =~ /up/i and %{status} !~ /up/i'). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--warning-*> diff --git a/src/network/alcatel/omniswitch/snmp/mode/virtualchassis.pm b/src/network/alcatel/omniswitch/snmp/mode/virtualchassis.pm index 2db8a5b50..017da89ca 100644 --- a/src/network/alcatel/omniswitch/snmp/mode/virtualchassis.pm +++ b/src/network/alcatel/omniswitch/snmp/mode/virtualchassis.pm @@ -133,17 +133,17 @@ Check virtual chassis. =item B<--unknown-chassis-status> Set unknown threshold for status. -Can used special variables like: %{role}, %{status}, %{mac} +You can use the following variables: %{role}, %{status}, %{mac} =item B<--warning-chassis-status> Set warning threshold for status. -Can used special variables like: %{role}, %{status}, %{mac} +You can use the following variables: %{role}, %{status}, %{mac} =item B<--critical-chassis-status> Set critical threshold for status (Default: %{status} !~ /init|running/) -Can used special variables like: %{role}, %{status}, %{mac} +You can use the following variables: %{role}, %{status}, %{mac} =item B<--warning-*> B<--critical-*> diff --git a/src/network/alcatel/oxe/snmp/mode/trunks.pm b/src/network/alcatel/oxe/snmp/mode/trunks.pm index ec906e4d1..6a0f468bd 100644 --- a/src/network/alcatel/oxe/snmp/mode/trunks.pm +++ b/src/network/alcatel/oxe/snmp/mode/trunks.pm @@ -199,12 +199,12 @@ Filter by trunk name (regexp can be used). =item B<--warning-trunk-status> Set warning threshold for status -Can used special variables like: %{trunkstatus} +You can use the following variables: %{trunkstatus} =item B<--critical-trunk-status> Set critical threshold for status (Default: '%{trunkstatus} =~ /oos/i'). -Can used special variables like: %{trunkstatus} +You can use the following variables: %{trunkstatus} =item B<--warning-*> diff --git a/src/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm b/src/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm index b57102ee9..1296f414d 100644 --- a/src/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm +++ b/src/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm @@ -263,12 +263,12 @@ Filter by SAP name (can be a regexp). =item B<--warning-status> Set warning threshold for ib status. -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--critical-status> Set critical threshold for ib status (Default: '%{admin} =~ /up/i and %{status} !~ /up/i'). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--warning-*> diff --git a/src/network/aruba/aoscx/restapi/mode/vsx.pm b/src/network/aruba/aoscx/restapi/mode/vsx.pm index 1bc3b20ab..8b2e978b5 100644 --- a/src/network/aruba/aoscx/restapi/mode/vsx.pm +++ b/src/network/aruba/aoscx/restapi/mode/vsx.pm @@ -226,47 +226,47 @@ Check virtual switching extension. =item B<--unknown-device-status> Set unknown threshold for status. -Can used special variables like: %{role}, %{config_sync} +You can use the following variables: %{role}, %{config_sync} =item B<--warning-device-status> Set warning threshold for status. -Can used special variables like: %{role}, %{config_sync} +You can use the following variables: %{role}, %{config_sync} =item B<--critical-device-status> Set critical threshold for status. -Can used special variables like: %{role}, %{config_sync} +You can use the following variables: %{role}, %{config_sync} =item B<--unknown-isl-status> Set unknown threshold for status. -Can used special variables like: %{isl_status} +You can use the following variables: %{isl_status} =item B<--warning-isl-status> Set warning threshold for status. -Can used special variables like: %{isl_status} +You can use the following variables: %{isl_status} =item B<--critical-isl-status> Set critical threshold for status (Default: '%{isl_status} =~ /out_sync/'). -Can used special variables like: %{isl_status} +You can use the following variables: %{isl_status} =item B<--unknown-keepalive-status> Set unknown threshold for status. -Can used special variables like: %{keepalive_status} +You can use the following variables: %{keepalive_status} =item B<--warning-keepalive-status> Set warning threshold for status. -Can used special variables like: %{keepalive_status} +You can use the following variables: %{keepalive_status} =item B<--critical-keepalive-status> Set critical threshold for status (Default: '%{keepalive_status} =~ /out_of_sync_established|failed/'). -Can used special variables like: %{keepalive_status} +You can use the following variables: %{keepalive_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/aruba/aoscx/snmp/mode/vsf.pm b/src/network/aruba/aoscx/snmp/mode/vsf.pm index 106f24f0c..6c58b0560 100644 --- a/src/network/aruba/aoscx/snmp/mode/vsf.pm +++ b/src/network/aruba/aoscx/snmp/mode/vsf.pm @@ -236,32 +236,32 @@ Check vsf virtual chassis. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /no_split/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-member-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{role}, %{roleLast}, %{id} +You can use the following variables: %{status}, %{role}, %{roleLast}, %{id} =item B<--warning-member-status> Set warning threshold for status. -Can used special variables like: %{status}, %{role}, %{roleLast}, %{id} +You can use the following variables: %{status}, %{role}, %{roleLast}, %{id} =item B<--critical-member-status> Set critical threshold for status (Default: '%{role} ne %{roleLast} || %{status} !~ /ready|booting/i'). -Can used special variables like: %{status}, %{role}, %{roleLast}, %{id} +You can use the following variables: %{status}, %{role}, %{roleLast}, %{id} =item B<--warning-*> B<--critical-*> diff --git a/src/network/aruba/aoscx/snmp/mode/vsx.pm b/src/network/aruba/aoscx/snmp/mode/vsx.pm index 5ba35b16a..e3b7e1d02 100644 --- a/src/network/aruba/aoscx/snmp/mode/vsx.pm +++ b/src/network/aruba/aoscx/snmp/mode/vsx.pm @@ -253,47 +253,47 @@ Check virtual switching extension. =item B<--unknown-device-status> Set unknown threshold for status. -Can used special variables like: %{role}, %{config_sync} +You can use the following variables: %{role}, %{config_sync} =item B<--warning-device-status> Set warning threshold for status. -Can used special variables like: %{role}, %{config_sync} +You can use the following variables: %{role}, %{config_sync} =item B<--critical-device-status> Set critical threshold for status. -Can used special variables like: %{role}, %{config_sync} +You can use the following variables: %{role}, %{config_sync} =item B<--unknown-isl-status> Set unknown threshold for status. -Can used special variables like: %{isl_status} +You can use the following variables: %{isl_status} =item B<--warning-isl-status> Set warning threshold for status. -Can used special variables like: %{isl_status} +You can use the following variables: %{isl_status} =item B<--critical-isl-status> Set critical threshold for status (Default: '%{isl_status} =~ /outSync/'). -Can used special variables like: %{isl_status} +You can use the following variables: %{isl_status} =item B<--unknown-keepalive-status> Set unknown threshold for status. -Can used special variables like: %{keepalive_status} +You can use the following variables: %{keepalive_status} =item B<--warning-keepalive-status> Set warning threshold for status. -Can used special variables like: %{keepalive_status} +You can use the following variables: %{keepalive_status} =item B<--critical-keepalive-status> Set critical threshold for status (Default: '%{keepalive_status} =~ /outofSyncEstablished|failed/'). -Can used special variables like: %{keepalive_status} +You can use the following variables: %{keepalive_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/aruba/cppm/snmp/mode/interfaces.pm b/src/network/aruba/cppm/snmp/mode/interfaces.pm index 3e3e91643..57afcd56b 100644 --- a/src/network/aruba/cppm/snmp/mode/interfaces.pm +++ b/src/network/aruba/cppm/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/aruba/instant/snmp/mode/apusage.pm b/src/network/aruba/instant/snmp/mode/apusage.pm index a2a5a6f08..89d6e6668 100644 --- a/src/network/aruba/instant/snmp/mode/apusage.pm +++ b/src/network/aruba/instant/snmp/mode/apusage.pm @@ -231,12 +231,12 @@ Filter access point name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /up/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/aruba/instant/snmp/mode/ssidstatus.pm b/src/network/aruba/instant/snmp/mode/ssidstatus.pm index cd4e421b9..08beff166 100644 --- a/src/network/aruba/instant/snmp/mode/ssidstatus.pm +++ b/src/network/aruba/instant/snmp/mode/ssidstatus.pm @@ -136,12 +136,12 @@ Filter SSID name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /enable/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/network/aruba/orchestrator/restapi/mode/alarms.pm b/src/network/aruba/orchestrator/restapi/mode/alarms.pm index 11bf9b529..4d0e59229 100644 --- a/src/network/aruba/orchestrator/restapi/mode/alarms.pm +++ b/src/network/aruba/orchestrator/restapi/mode/alarms.pm @@ -174,12 +174,12 @@ Set timezone for creation time (Default is 'UTC'). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') -Can used special variables like: %{severity}, %{hostname}, %{name}, %{timeraised} +You can use the following variables: %{severity}, %{hostname}, %{name}, %{timeraised} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /major|critical/i'). -Can used special variables like: %{severity}, %{hostname}, %{name}, %{timeraised} +You can use the following variables: %{severity}, %{hostname}, %{name}, %{timeraised} =item B<--warning-*> B<--critical-*> diff --git a/src/network/aruba/orchestrator/restapi/mode/appliances.pm b/src/network/aruba/orchestrator/restapi/mode/appliances.pm index ccc7aed92..ee24c8dab 100644 --- a/src/network/aruba/orchestrator/restapi/mode/appliances.pm +++ b/src/network/aruba/orchestrator/restapi/mode/appliances.pm @@ -169,17 +169,17 @@ Filter appliances by group. =item B<--unknown-status> Set unknown threshold for status (Default: '%{state} =~ /unknown|unreachable/i'). -Can used special variables like: %{state}, %{hostname} +You can use the following variables: %{state}, %{hostname} =item B<--warning-status> Set warning threshold for status (Default: '%{state} =~ /unsupportedVersion|outOfSynchronization/i'). -Can used special variables like: %{state}, %{hostname} +You can use the following variables: %{state}, %{hostname} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{hostname} +You can use the following variables: %{state}, %{hostname} =item B<--warning-*> B<--critical-*> diff --git a/src/network/athonet/epc/snmp/mode/interfacesdiameter.pm b/src/network/athonet/epc/snmp/mode/interfacesdiameter.pm index b27f08c37..c63357696 100644 --- a/src/network/athonet/epc/snmp/mode/interfacesdiameter.pm +++ b/src/network/athonet/epc/snmp/mode/interfacesdiameter.pm @@ -216,32 +216,32 @@ Filter interfaces by owner (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name}, %{owner} +You can use the following variables: %{status}, %{name}, %{owner} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{owner} +You can use the following variables: %{status}, %{name}, %{owner} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{name}, %{owner} +You can use the following variables: %{status}, %{name}, %{owner} =item B<--unknown-transport-status> Set unknown threshold for status. -Can used special variables like: %{transport_status}, %{transport_type}, %{name} +You can use the following variables: %{transport_status}, %{transport_type}, %{name} =item B<--warning-transport-status> Set warning threshold for status. -Can used special variables like: %{transport_status}, %{transport_type}, %{name} +You can use the following variables: %{transport_status}, %{transport_type}, %{name} =item B<--critical-transport-status> Set critical threshold for status (Default: '%{transport_status} =~ /down/i'). -Can used special variables like: %{transport_status}, %{transport_type}, %{name} +You can use the following variables: %{transport_status}, %{transport_type}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/athonet/epc/snmp/mode/interfacesga.pm b/src/network/athonet/epc/snmp/mode/interfacesga.pm index 1215c4bdf..84a48427b 100644 --- a/src/network/athonet/epc/snmp/mode/interfacesga.pm +++ b/src/network/athonet/epc/snmp/mode/interfacesga.pm @@ -168,17 +168,17 @@ Filter interfaces by peer address (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{local_address}, %{peer_address}, %{name} +You can use the following variables: %{status}, %{local_address}, %{peer_address}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{local_address}, %{peer_address}, %{name} +You can use the following variables: %{status}, %{local_address}, %{peer_address}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{local_address}, %{peer_address}, %{name} +You can use the following variables: %{status}, %{local_address}, %{peer_address}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/athonet/epc/snmp/mode/interfacesgtpc.pm b/src/network/athonet/epc/snmp/mode/interfacesgtpc.pm index 4fa956bd6..5e569cf4b 100644 --- a/src/network/athonet/epc/snmp/mode/interfacesgtpc.pm +++ b/src/network/athonet/epc/snmp/mode/interfacesgtpc.pm @@ -189,17 +189,17 @@ Filter interfaces by type (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{source_address}, %{destination_address} +You can use the following variables: %{status}, %{source_address}, %{destination_address} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{source_address}, %{destination_address} +You can use the following variables: %{status}, %{source_address}, %{destination_address} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{source_address}, %{destination_address} +You can use the following variables: %{status}, %{source_address}, %{destination_address} =item B<--warning-*> B<--critical-*> diff --git a/src/network/athonet/epc/snmp/mode/interfaceslte.pm b/src/network/athonet/epc/snmp/mode/interfaceslte.pm index 58b89752d..c9590e380 100644 --- a/src/network/athonet/epc/snmp/mode/interfaceslte.pm +++ b/src/network/athonet/epc/snmp/mode/interfaceslte.pm @@ -431,17 +431,17 @@ Filter interfaces by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{sctp_status}, %{s1ap_status}, %{name} +You can use the following variables: %{sctp_status}, %{s1ap_status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{sctp_status}, %{s1ap_status}, %{name} +You can use the following variables: %{sctp_status}, %{s1ap_status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{sctp_status} =~ /down/i || %{s1ap_status} =~ /down/i'). -Can used special variables like: %{sctp_status}, %{s1ap_status}, %{name} +You can use the following variables: %{sctp_status}, %{s1ap_status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/atrica/snmp/mode/connections.pm b/src/network/atrica/snmp/mode/connections.pm index 126155d1c..38f7c54e1 100644 --- a/src/network/atrica/snmp/mode/connections.pm +++ b/src/network/atrica/snmp/mode/connections.pm @@ -410,7 +410,7 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up" or =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--critical-status> @@ -418,7 +418,7 @@ Set critical threshold for status. Default (depends of the atrica release): '%{admstatus} eq "on" and %{opstatus} ne "inService"' '%{admstatus} eq "up" and %{opstatus} ne "up"' -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/atto/fibrebridge/snmp/mode/fcportusage.pm b/src/network/atto/fibrebridge/snmp/mode/fcportusage.pm index b8bdccf38..88303079a 100644 --- a/src/network/atto/fibrebridge/snmp/mode/fcportusage.pm +++ b/src/network/atto/fibrebridge/snmp/mode/fcportusage.pm @@ -206,12 +206,12 @@ Filter name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admin} =~ /enabled/ and %{status} !~ /online/'). -Can used special variables like: %{admin}, %{status}, %{display} +You can use the following variables: %{admin}, %{status}, %{display} =back diff --git a/src/network/audiocodes/snmp/mode/trunkstatus.pm b/src/network/audiocodes/snmp/mode/trunkstatus.pm index d062200df..3ea737ed1 100644 --- a/src/network/audiocodes/snmp/mode/trunkstatus.pm +++ b/src/network/audiocodes/snmp/mode/trunkstatus.pm @@ -203,12 +203,12 @@ Filter by name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{alarm}, %{dchannel}, %{state} +You can use the following variables: %{display}, %{alarm}, %{dchannel}, %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i'). -Can used special variables like: %{display}, %{alarm}, %{dchannel}, %{state} +You can use the following variables: %{display}, %{alarm}, %{dchannel}, %{state} =item B<--warning-*> diff --git a/src/network/barracuda/cloudgen/snmp/mode/boxservice.pm b/src/network/barracuda/cloudgen/snmp/mode/boxservice.pm index cd3861feb..7429f44be 100644 --- a/src/network/barracuda/cloudgen/snmp/mode/boxservice.pm +++ b/src/network/barracuda/cloudgen/snmp/mode/boxservice.pm @@ -153,12 +153,12 @@ Check box services status. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^started$/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--filter-name> diff --git a/src/network/barracuda/cloudgen/snmp/mode/serverservice.pm b/src/network/barracuda/cloudgen/snmp/mode/serverservice.pm index c0db10a3b..26907ce21 100644 --- a/src/network/barracuda/cloudgen/snmp/mode/serverservice.pm +++ b/src/network/barracuda/cloudgen/snmp/mode/serverservice.pm @@ -153,12 +153,12 @@ Check server services status. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^started$/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--filter-name> diff --git a/src/network/barracuda/cloudgen/snmp/mode/vpnstatus.pm b/src/network/barracuda/cloudgen/snmp/mode/vpnstatus.pm index bd8a121f7..632572ae0 100644 --- a/src/network/barracuda/cloudgen/snmp/mode/vpnstatus.pm +++ b/src/network/barracuda/cloudgen/snmp/mode/vpnstatus.pm @@ -151,12 +151,12 @@ Check VPNs status. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^down$/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--filter-name> diff --git a/src/network/beeware/snmp/mode/reverseproxyusage.pm b/src/network/beeware/snmp/mode/reverseproxyusage.pm index 7e78721c5..6306d631a 100644 --- a/src/network/beeware/snmp/mode/reverseproxyusage.pm +++ b/src/network/beeware/snmp/mode/reverseproxyusage.pm @@ -182,12 +182,12 @@ Filter reverse proxy (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /running/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--warning-*> diff --git a/src/network/brocade/snmp/mode/interfaces.pm b/src/network/brocade/snmp/mode/interfaces.pm index 1705ec81d..5d74f4563 100644 --- a/src/network/brocade/snmp/mode/interfaces.pm +++ b/src/network/brocade/snmp/mode/interfaces.pm @@ -298,12 +298,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cambium/epmp/snmp/mode/interfaces.pm b/src/network/cambium/epmp/snmp/mode/interfaces.pm index 95c86e839..2b5348161 100644 --- a/src/network/cambium/epmp/snmp/mode/interfaces.pm +++ b/src/network/cambium/epmp/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cambium/epmp/snmp/mode/license.pm b/src/network/cambium/epmp/snmp/mode/license.pm index f4ffd25e6..c57ae931e 100644 --- a/src/network/cambium/epmp/snmp/mode/license.pm +++ b/src/network/cambium/epmp/snmp/mode/license.pm @@ -108,17 +108,17 @@ Check Cambium license status. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /validation fail|not provided/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /not valid/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/network/checkpoint/snmp/mode/rausers.pm b/src/network/checkpoint/snmp/mode/rausers.pm index 4695ad45c..8708084b7 100644 --- a/src/network/checkpoint/snmp/mode/rausers.pm +++ b/src/network/checkpoint/snmp/mode/rausers.pm @@ -149,12 +149,12 @@ Filter on remote access users (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{display}, %{status} +You can use the following variables: %{display}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/checkpoint/snmp/mode/vpnstatus.pm b/src/network/checkpoint/snmp/mode/vpnstatus.pm index 7fee5b423..2f4cee651 100644 --- a/src/network/checkpoint/snmp/mode/vpnstatus.pm +++ b/src/network/checkpoint/snmp/mode/vpnstatus.pm @@ -166,12 +166,12 @@ Filter vpn name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{type}, %{status}, %{display} +You can use the following variables: %{type}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{type} eq "permanent" and %{status} =~ /down/i'). -Can used special variables like: %{type}, %{status}, %{display} +You can use the following variables: %{type}, %{status}, %{display} =item B<--buggy-snmp> diff --git a/src/network/cisco/aci/apic/restapi/mode/fabric.pm b/src/network/cisco/aci/apic/restapi/mode/fabric.pm index e616ba2c9..c44cd1d63 100644 --- a/src/network/cisco/aci/apic/restapi/mode/fabric.pm +++ b/src/network/cisco/aci/apic/restapi/mode/fabric.pm @@ -114,13 +114,13 @@ Check fabrics. =item B<--warning-health> Set warning for the health level -Can used special variables like: %{current}, %{previous}. +You can use the following variables: %{current}, %{previous}. example: --warning-health='%{previous} < %{current}' =item B<--critical-health> Set critical for the health level -Can used special variables like: %{current}, %{previous}. +You can use the following variables: %{current}, %{previous}. example: --critical-health='%{current} < 98' =back diff --git a/src/network/cisco/aci/apic/restapi/mode/tenant.pm b/src/network/cisco/aci/apic/restapi/mode/tenant.pm index 8a497e561..014240dc4 100644 --- a/src/network/cisco/aci/apic/restapi/mode/tenant.pm +++ b/src/network/cisco/aci/apic/restapi/mode/tenant.pm @@ -125,13 +125,13 @@ Regexp filter on the tenant name =item B<--warning-health> Set warning for the health level -Can used special variables like: %{current}, %{previous}. +You can use the following variables: %{current}, %{previous}. example: --warning-health='%{previous} < %{current}' =item B<--critical-health> Set critical for the health level -Can used special variables like: %{current}, %{previous}. +You can use the following variables: %{current}, %{previous}. example: --critical-health='%{current} < 98' =back diff --git a/src/network/cisco/asa/snmp/mode/failover.pm b/src/network/cisco/asa/snmp/mode/failover.pm index 498f05f15..3604fb351 100644 --- a/src/network/cisco/asa/snmp/mode/failover.pm +++ b/src/network/cisco/asa/snmp/mode/failover.pm @@ -154,12 +154,12 @@ Example: --filter-counters='^status$' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{primaryStateLast}, %{secondaryStateLast}, %{primaryState}, %{secondaryState} +You can use the following variables: %{primaryStateLast}, %{secondaryStateLast}, %{primaryState}, %{secondaryState} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{primaryStateLast}, %{secondaryStateLast}, %{primaryState}, %{secondaryState} +You can use the following variables: %{primaryStateLast}, %{secondaryStateLast}, %{primaryState}, %{secondaryState} =item B<--warning-*> diff --git a/src/network/cisco/callmanager/snmp/mode/ccmusage.pm b/src/network/cisco/callmanager/snmp/mode/ccmusage.pm index e71bd69a1..2fa6ea75d 100644 --- a/src/network/cisco/callmanager/snmp/mode/ccmusage.pm +++ b/src/network/cisco/callmanager/snmp/mode/ccmusage.pm @@ -166,12 +166,12 @@ Example: --filter-counters='phone' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /up/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/callmanager/snmp/mode/ctiusage.pm b/src/network/cisco/callmanager/snmp/mode/ctiusage.pm index 3498ae4ed..d9f3f62da 100644 --- a/src/network/cisco/callmanager/snmp/mode/ctiusage.pm +++ b/src/network/cisco/callmanager/snmp/mode/ctiusage.pm @@ -157,12 +157,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^registered/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/callmanager/snmp/mode/gatewayusage.pm b/src/network/cisco/callmanager/snmp/mode/gatewayusage.pm index b4f9ebe9b..e9ba6d839 100644 --- a/src/network/cisco/callmanager/snmp/mode/gatewayusage.pm +++ b/src/network/cisco/callmanager/snmp/mode/gatewayusage.pm @@ -148,12 +148,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^registered/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm b/src/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm index 9d6bfc811..86db7788f 100644 --- a/src/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm +++ b/src/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm @@ -148,12 +148,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^registered/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/cisco/callmanager/snmp/mode/phoneusage.pm b/src/network/cisco/callmanager/snmp/mode/phoneusage.pm index 9bf91ee67..459b1fbd1 100644 --- a/src/network/cisco/callmanager/snmp/mode/phoneusage.pm +++ b/src/network/cisco/callmanager/snmp/mode/phoneusage.pm @@ -176,12 +176,12 @@ Filter phone by description (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{description} +You can use the following variables: %{status}, %{name}, %{description} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^registered/'). -Can used special variables like: %{status}, %{name}, %{description} +You can use the following variables: %{status}, %{name}, %{description} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/callmanager/snmp/mode/voicemailusage.pm b/src/network/cisco/callmanager/snmp/mode/voicemailusage.pm index 7cb8a02f5..e537975fc 100644 --- a/src/network/cisco/callmanager/snmp/mode/voicemailusage.pm +++ b/src/network/cisco/callmanager/snmp/mode/voicemailusage.pm @@ -148,12 +148,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /^registered/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/callmanager/sxml/mode/services.pm b/src/network/cisco/callmanager/sxml/mode/services.pm index 99eb83e2f..ac637e927 100644 --- a/src/network/cisco/callmanager/sxml/mode/services.pm +++ b/src/network/cisco/callmanager/sxml/mode/services.pm @@ -185,17 +185,17 @@ Filter services by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{reason}, %{name} +You can use the following variables: %{status}, %{reason}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{reason}, %{name} +You can use the following variables: %{status}, %{reason}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /starting|started/i and %{reason} !~ /service not activate/i'). -Can used special variables like: %{status}, %{reason}, %{name} +You can use the following variables: %{status}, %{reason}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/firepower/fmc/restapi/mode/devices.pm b/src/network/cisco/firepower/fmc/restapi/mode/devices.pm index 960f96f30..68fb90e4a 100644 --- a/src/network/cisco/firepower/fmc/restapi/mode/devices.pm +++ b/src/network/cisco/firepower/fmc/restapi/mode/devices.pm @@ -191,17 +191,17 @@ Filter devices by name (Can be a regexp). =item B<--unknown-device-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-device-status> Set warning threshold for status (Default: '%{status} =~ /yellow/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-device-status> Set critical threshold for status (Default: '%{status} =~ /red|black/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/firepower/fxos/snmp/mode/faults.pm b/src/network/cisco/firepower/fxos/snmp/mode/faults.pm index ef3e3cd2a..ee924eec3 100644 --- a/src/network/cisco/firepower/fxos/snmp/mode/faults.pm +++ b/src/network/cisco/firepower/fxos/snmp/mode/faults.pm @@ -225,12 +225,12 @@ Check faults. =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/). -Can used special variables like: %{description}, %{object}, %{severity}, %{type}, %{acknowledged}, %{since} +You can use the following variables: %{description}, %{object}, %{severity}, %{type}, %{acknowledged}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /major|critical/'). -Can used special variables like: %{description}, %{object}, %{severity}, %{type}, %{since} +You can use the following variables: %{description}, %{object}, %{severity}, %{type}, %{since} =item B<--timezone> diff --git a/src/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm b/src/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm index 8cd8777a9..03402da5a 100644 --- a/src/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm +++ b/src/network/cisco/meraki/cloudcontroller/restapi/mode/devices.pm @@ -608,47 +608,47 @@ Skip port traffic counters if port status is disconnected. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /alerting/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--unknown-link-status> Set unknown threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-link-status> Set warning threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--critical-link-status> Set critical threshold for status (Default: '%{link_status} =~ /failed/i'). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--unknown-port-status> Set unknown threshold for status. -Can used special variables like: %{port_status}, %{port_enabled}, %{display} +You can use the following variables: %{port_status}, %{port_enabled}, %{display} =item B<--warning-port-status> Set warning threshold for status. -Can used special variables like: %{port_status}, %{port_enabled}, %{display} +You can use the following variables: %{port_status}, %{port_enabled}, %{display} =item B<--critical-port-status> Set critical threshold for status (Default: '%{port_enabled} == 1 and %{port_status} !~ /^connected/i'). -Can used special variables like: %{port_status}, %{port_enabled}, %{display} +You can use the following variables: %{port_status}, %{port_enabled}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm b/src/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm index 88c41804f..19cf1424b 100644 --- a/src/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm +++ b/src/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm @@ -388,12 +388,12 @@ Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /offline/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/cisco/prime/restapi/mode/apusage.pm b/src/network/cisco/prime/restapi/mode/apusage.pm index 2a90aea2c..9415da0a9 100644 --- a/src/network/cisco/prime/restapi/mode/apusage.pm +++ b/src/network/cisco/prime/restapi/mode/apusage.pm @@ -236,12 +236,12 @@ Can be: 'ap-clients', 'ap-uptime', 'ap-lwappuptime', =item B<--warning-ap-status> Set warning threshold for status (Default: '%{admin_status} =~ /enable/i && %{status} =~ /minor|warning/i') -Can used special variables like: %{name}, %{status}, %{controller}, %{admin_status} +You can use the following variables: %{name}, %{status}, %{controller}, %{admin_status} =item B<--critical-ap-status> Set critical threshold for status (Default: '%{admin_status} =~ /enable/i && %{status} =~ /major|critical/i'). -Can used special variables like: %{name}, %{status}, %{controller}, %{admin_status} +You can use the following variables: %{name}, %{status}, %{controller}, %{admin_status} =item B<--reload-cache-time> diff --git a/src/network/cisco/standard/ssh/mode/voicedialpeer.pm b/src/network/cisco/standard/ssh/mode/voicedialpeer.pm index 48d2caea2..501d98a27 100644 --- a/src/network/cisco/standard/ssh/mode/voicedialpeer.pm +++ b/src/network/cisco/standard/ssh/mode/voicedialpeer.pm @@ -164,17 +164,17 @@ Filter name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{admin}, %{oper}, %{keepalive}, %{display} +You can use the following variables: %{admin}, %{oper}, %{keepalive}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{admin}, %{oper}, %{keepalive}, %{display} +You can use the following variables: %{admin}, %{oper}, %{keepalive}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admin} eq "up" and %{oper} eq "down"'). -Can used special variables like: %{admin}, %{oper}, %{keepalive}, %{display} +You can use the following variables: %{admin}, %{oper}, %{keepalive}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/cisco/umbrella/snmp/mode/appliance.pm b/src/network/cisco/umbrella/snmp/mode/appliance.pm index b5fac8f66..9dbd2ff68 100644 --- a/src/network/cisco/umbrella/snmp/mode/appliance.pm +++ b/src/network/cisco/umbrella/snmp/mode/appliance.pm @@ -95,12 +95,12 @@ Check VA health. =item B<--warning-status> Set warning threshold for status. (Default: '%{status} =~ /yellow/') -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status. (Default: '%{status} =~ /red/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/network/cisco/wap/snmp/mode/virtualaccesspoints.pm b/src/network/cisco/wap/snmp/mode/virtualaccesspoints.pm index 046ab3780..c1a66961f 100644 --- a/src/network/cisco/wap/snmp/mode/virtualaccesspoints.pm +++ b/src/network/cisco/wap/snmp/mode/virtualaccesspoints.pm @@ -165,17 +165,17 @@ Filter virtual access points by description (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{description}, %{admin_status}, %{operational_status} +You can use the following variables: %{description}, %{admin_status}, %{operational_status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{description}, %{admin_status}, %{operational_status} +You can use the following variables: %{description}, %{admin_status}, %{operational_status} =item B<--critical-status> Set critical threshold for status (Default: '%{admin_status} eq "up" and %{operational_status} eq "down"'). -Can used special variables like: %{description}, %{admin_status}, %{operational_status} +You can use the following variables: %{description}, %{admin_status}, %{operational_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/citrix/sdx/snmp/mode/srusage.pm b/src/network/citrix/sdx/snmp/mode/srusage.pm index dbedb2f09..bd9bad445 100644 --- a/src/network/citrix/sdx/snmp/mode/srusage.pm +++ b/src/network/citrix/sdx/snmp/mode/srusage.pm @@ -228,12 +228,12 @@ Filter storage repository name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /good/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/colubris/snmp/mode/apusage.pm b/src/network/colubris/snmp/mode/apusage.pm index 358ff6607..31af1a52c 100644 --- a/src/network/colubris/snmp/mode/apusage.pm +++ b/src/network/colubris/snmp/mode/apusage.pm @@ -231,12 +231,12 @@ Can be: 'total-ap', 'total-users', 'ap-users'. =item B<--warning-ap-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-ap-status> Set critical threshold for status (Default: '%{state} eq "disconnected"'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =back diff --git a/src/network/dell/nseries/snmp/mode/interfaces.pm b/src/network/dell/nseries/snmp/mode/interfaces.pm index c25d95b51..212daf99f 100644 --- a/src/network/dell/nseries/snmp/mode/interfaces.pm +++ b/src/network/dell/nseries/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/denyall/snmp/mode/reverseproxy.pm b/src/network/denyall/snmp/mode/reverseproxy.pm index e6e16045f..a16849735 100644 --- a/src/network/denyall/snmp/mode/reverseproxy.pm +++ b/src/network/denyall/snmp/mode/reverseproxy.pm @@ -197,17 +197,17 @@ Filter reverse proxy by UID (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{uid} +You can use the following variables: %{status}, %{uid} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{uid} +You can use the following variables: %{status}, %{uid} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{uid} +You can use the following variables: %{status}, %{uid} =item B<--warning-*> B<--critical-*> diff --git a/src/network/digi/sarian/snmp/mode/gprs.pm b/src/network/digi/sarian/snmp/mode/gprs.pm index 1ede8f6cc..681f3ed27 100644 --- a/src/network/digi/sarian/snmp/mode/gprs.pm +++ b/src/network/digi/sarian/snmp/mode/gprs.pm @@ -181,12 +181,12 @@ Example: --filter-counters='signal|technology' =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{registered}, %{attachement} +You can use the following variables: %{registered}, %{attachement} =item B<--critical-status> Set critical threshold for status (Default: '%{attachement} eq "attached" and %{registered} !~ /registeredHostNetwork|registeredRoaming/' -Can used special variables like: %{registered}, %{attachement} +You can use the following variables: %{registered}, %{attachement} =item B<--warning-technology> diff --git a/src/network/dlink/standard/snmp/mode/interfaces.pm b/src/network/dlink/standard/snmp/mode/interfaces.pm index 903089e35..daead9302 100644 --- a/src/network/dlink/standard/snmp/mode/interfaces.pm +++ b/src/network/dlink/standard/snmp/mode/interfaces.pm @@ -169,12 +169,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{errdisable}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/dlink/standard/snmp/mode/stack.pm b/src/network/dlink/standard/snmp/mode/stack.pm index 50c69fda8..b9dcd9a5c 100644 --- a/src/network/dlink/standard/snmp/mode/stack.pm +++ b/src/network/dlink/standard/snmp/mode/stack.pm @@ -245,32 +245,32 @@ Check stack. =item B<--unknown-member-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{role}, %{roleLast}, %{status}, %{display} +You can use the following variables: %{role}, %{roleLast}, %{status}, %{display} =item B<--warning-member-status> Set warning threshold for status (Default: '%{status} =~ /codeUpdate/i'). -Can used special variables like: %{role}, %{roleLast}, %{status}, %{display} +You can use the following variables: %{role}, %{roleLast}, %{status}, %{display} =item B<--critical-member-status> Set critical threshold for status (Default: '%{role} ne %{roleLast} || %{status} =~ /unsupported|codeMismatch/i'). -Can used special variables like: %{role}, %{roleLast}, %{status}, %{display} +You can use the following variables: %{role}, %{roleLast}, %{status}, %{display} =item B<--unknown-link-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-link-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-link-status> Set critical threshold for status (Default: '%{status} eq "down"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/enterasys/snmp/mode/interfaces.pm b/src/network/enterasys/snmp/mode/interfaces.pm index b8df97746..605769b5d 100644 --- a/src/network/enterasys/snmp/mode/interfaces.pm +++ b/src/network/enterasys/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/evertz/AEA47721/snmp/mode/streamstatus.pm b/src/network/evertz/AEA47721/snmp/mode/streamstatus.pm index 10ce84a34..ae2bbdaf0 100644 --- a/src/network/evertz/AEA47721/snmp/mode/streamstatus.pm +++ b/src/network/evertz/AEA47721/snmp/mode/streamstatus.pm @@ -170,22 +170,22 @@ Check video/audio stream status. =item B<--warning-audio-status> Set warning threshold for device status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-audio-status> Set critical threshold for device status (Default: '%{status} =~ /loss/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-video-status> Set warning threshold for device connection status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-video-status> Set critical threshold for device connection status (Default: '%{status} =~ /loss|unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm b/src/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm index 132f4e1fe..2afcbafe4 100644 --- a/src/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm +++ b/src/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm @@ -130,12 +130,12 @@ Check video stream status. =item B<--warning-video-status> Set warning threshold for device connection status. -Can used special variables like: %{video_locked}, %{display} +You can use the following variables: %{video_locked}, %{display} =item B<--critical-video-status> Set critical threshold for device connection status (Default: '%{video_locked} =~ /notLocked/i'). -Can used special variables like: %{video_locked}, %{display} +You can use the following variables: %{video_locked}, %{display} =back diff --git a/src/network/extreme/snmp/mode/interfaces.pm b/src/network/extreme/snmp/mode/interfaces.pm index b18b1b229..d9631333f 100644 --- a/src/network/extreme/snmp/mode/interfaces.pm +++ b/src/network/extreme/snmp/mode/interfaces.pm @@ -122,12 +122,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/extreme/snmp/mode/stack.pm b/src/network/extreme/snmp/mode/stack.pm index 212c48c01..16a4432a3 100644 --- a/src/network/extreme/snmp/mode/stack.pm +++ b/src/network/extreme/snmp/mode/stack.pm @@ -244,32 +244,32 @@ Check stack status. =item B<--unknown-member-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{role}, %{roleLast} +You can use the following variables: %{role}, %{roleLast} =item B<--warning-member-status> Set warning threshold for status (Default: '%{status} eq "mismatch"'). -Can used special variables like: %{role}, %{roleLast} +You can use the following variables: %{role}, %{roleLast} =item B<--critical-member-status> Set critical threshold for status (Default: '%{role} ne %{roleLast} || %{status} eq "down"'). -Can used special variables like: %{role}, %{roleLast} +You can use the following variables: %{role}, %{roleLast} =item B<--unknown-port-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-port-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--critical-port-status> Set critical threshold for status (Default: '%{link_status} ne "up"'). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =back diff --git a/src/network/f5/bigip/snmp/mode/failover.pm b/src/network/f5/bigip/snmp/mode/failover.pm index 207e5e48b..2b67799ce 100644 --- a/src/network/f5/bigip/snmp/mode/failover.pm +++ b/src/network/f5/bigip/snmp/mode/failover.pm @@ -188,22 +188,22 @@ Only display some counters (regexp can be used). =item B<--warning-sync-status> Set warning threshold for sync status -Can used special variables like: %{syncstatus} +You can use the following variables: %{syncstatus} =item B<--critical-sync-status> Set critical threshold for sync status (Default: '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/'). -Can used special variables like: %{syncstatus} +You can use the following variables: %{syncstatus} =item B<--warning-failover-status> Set warning threshold for failover status -Can used special variables like: %{failoverstatus} +You can use the following variables: %{failoverstatus} =item B<--critical-failover-status> Set critical threshold for failover status (Default: '%{failoverstatus} =~ /unknown/'). -Can used special variables like: %{failoverstatus} +You can use the following variables: %{failoverstatus} =back diff --git a/src/network/f5/bigip/snmp/mode/nodestatus.pm b/src/network/f5/bigip/snmp/mode/nodestatus.pm index 56449f323..9c962ed56 100644 --- a/src/network/f5/bigip/snmp/mode/nodestatus.pm +++ b/src/network/f5/bigip/snmp/mode/nodestatus.pm @@ -195,17 +195,17 @@ Filter by name (regexp can be used). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{state} eq "enabled" and %{status} eq "yellow"'). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} eq "enabled" and %{status} eq "red"'). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/f5/bigip/snmp/mode/poolstatus.pm b/src/network/f5/bigip/snmp/mode/poolstatus.pm index 8a0ff203c..dfd93fa39 100644 --- a/src/network/f5/bigip/snmp/mode/poolstatus.pm +++ b/src/network/f5/bigip/snmp/mode/poolstatus.pm @@ -329,32 +329,32 @@ Filter by name (regexp can be used). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{status}, %{membersAllDisabled}, %{display} +You can use the following variables: %{state}, %{status}, %{membersAllDisabled}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{membersAllDisabled} eq "no" and %{state} eq "enabled" and %{status} eq "yellow"'). -Can used special variables like: %{state}, %{status}, %{membersAllDisabled}, %{display} +You can use the following variables: %{state}, %{status}, %{membersAllDisabled}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{membersAllDisabled} eq "no" and %{state} eq "enabled" and %{status} eq "red"'). -Can used special variables like: %{state}, %{status}, %{membersAllDisabled}, %{display} +You can use the following variables: %{state}, %{status}, %{membersAllDisabled}, %{display} =item B<--unknown-member-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{status}, %{poolName}, %{nodeName} +You can use the following variables: %{state}, %{status}, %{poolName}, %{nodeName} =item B<--warning-member-status> Set warning threshold for status. -Can used special variables like: %{state}, %{status}, %{poolName}, %{nodeName} +You can use the following variables: %{state}, %{status}, %{poolName}, %{nodeName} =item B<--critical-member-status> Set critical threshold for status. -Can used special variables like: %{state}, %{status}, %{poolName}, %{nodeName} +You can use the following variables: %{state}, %{status}, %{poolName}, %{nodeName} =item B<--warning-*> B<--critical-*> diff --git a/src/network/f5/bigip/snmp/mode/trunks.pm b/src/network/f5/bigip/snmp/mode/trunks.pm index 64892a16b..a6eee131e 100644 --- a/src/network/f5/bigip/snmp/mode/trunks.pm +++ b/src/network/f5/bigip/snmp/mode/trunks.pm @@ -476,32 +476,32 @@ Monitor trunk interfaces. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /uninitialized|down/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--unknown-interface-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-interface-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-interface-status> Set critical threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/f5/bigip/snmp/mode/virtualserverstatus.pm b/src/network/f5/bigip/snmp/mode/virtualserverstatus.pm index 2bcc99c6d..c134ce176 100644 --- a/src/network/f5/bigip/snmp/mode/virtualserverstatus.pm +++ b/src/network/f5/bigip/snmp/mode/virtualserverstatus.pm @@ -185,17 +185,17 @@ Filter by name (regexp can be used). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{state} eq "enabled" and %{status} eq "yellow"'). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} eq "enabled" and %{status} eq "red"'). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/fortinet/fortiadc/snmp/mode/interfaces.pm b/src/network/fortinet/fortiadc/snmp/mode/interfaces.pm index a7de81f7c..1ab4e9b0e 100644 --- a/src/network/fortinet/fortiadc/snmp/mode/interfaces.pm +++ b/src/network/fortinet/fortiadc/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/fortinet/fortiadc/snmp/mode/security.pm b/src/network/fortinet/fortiadc/snmp/mode/security.pm index 6812ef02b..2a9633fe9 100644 --- a/src/network/fortinet/fortiadc/snmp/mode/security.pm +++ b/src/network/fortinet/fortiadc/snmp/mode/security.pm @@ -85,12 +85,12 @@ Check security. =item B<--warning-ddos-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-ddos-status> Set critical threshold for status (Default: '%{status} eq "attacking"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/network/fortinet/fortiadc/snmp/mode/virtualservers.pm b/src/network/fortinet/fortiadc/snmp/mode/virtualservers.pm index 774ae4e2a..b4704a425 100644 --- a/src/network/fortinet/fortiadc/snmp/mode/virtualservers.pm +++ b/src/network/fortinet/fortiadc/snmp/mode/virtualservers.pm @@ -262,17 +262,17 @@ Filter virtual servers by vdom name. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{state}, %{name}, %{vdom} +You can use the following variables: %{status}, %{state}, %{name}, %{vdom} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{state}, %{name}, %{vdom} +You can use the following variables: %{status}, %{state}, %{name}, %{vdom} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "unhealthy"'). -Can used special variables like: %{status}, %{state}, %{name}, %{vdom} +You can use the following variables: %{status}, %{state}, %{name}, %{vdom} =item B<--warning-*> B<--critical-*> diff --git a/src/network/fortinet/fortiauthenticator/snmp/mode/ha.pm b/src/network/fortinet/fortiauthenticator/snmp/mode/ha.pm index b41a707a0..cdfbc4110 100644 --- a/src/network/fortinet/fortiauthenticator/snmp/mode/ha.pm +++ b/src/network/fortinet/fortiauthenticator/snmp/mode/ha.pm @@ -111,12 +111,12 @@ Check high-availability status. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{ha_status}, %{ha_status_last} +You can use the following variables: %{ha_status}, %{ha_status_last} =item B<--critical-status> Set critical threshold for status (Default: '%{ha_status} ne %{ha_status_last}'). -Can used special variables like: %{ha_status}, %{ha_status_last} +You can use the following variables: %{ha_status}, %{ha_status_last} =back diff --git a/src/network/fortinet/fortigate/restapi/mode/health.pm b/src/network/fortinet/fortigate/restapi/mode/health.pm index cf6e441a6..b698e0e56 100644 --- a/src/network/fortinet/fortigate/restapi/mode/health.pm +++ b/src/network/fortinet/fortigate/restapi/mode/health.pm @@ -108,17 +108,17 @@ Filter vdom by name. =item B<--unknown-health> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-health> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-health> Set critical threshold for status (Default: '%{status} !~ /success/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =back diff --git a/src/network/fortinet/fortigate/restapi/mode/licenses.pm b/src/network/fortinet/fortigate/restapi/mode/licenses.pm index 432d6780e..fc632919b 100644 --- a/src/network/fortinet/fortigate/restapi/mode/licenses.pm +++ b/src/network/fortinet/fortigate/restapi/mode/licenses.pm @@ -178,12 +178,12 @@ Filter licenses by name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{status}. +You can use the following variables: %{name}, %{status}. =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /expired/i'). -Can used special variables like: %{name}, %{status}. +You can use the following variables: %{name}, %{status}. =item B<--unit> diff --git a/src/network/fortinet/fortimanager/snmp/mode/devicestatus.pm b/src/network/fortinet/fortimanager/snmp/mode/devicestatus.pm index 6407e31b6..0eb4993be 100644 --- a/src/network/fortinet/fortimanager/snmp/mode/devicestatus.pm +++ b/src/network/fortinet/fortimanager/snmp/mode/devicestatus.pm @@ -226,52 +226,52 @@ Filter by device name (can be a regexp). =item B<--warning-device-status> Set warning threshold for device status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-device-status> Set critical threshold for device status -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-device-con-status> Set warning threshold for device connection status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-device-con-status> Set critical threshold for device connection status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-device-db-status> Set warning threshold for device DB status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-device-db-status> Set critical threshold for device DB status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-device-config-status> Set warning threshold for device configuration status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-device-config-status> Set critical threshold for device configuration status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-device-policy-package-status> Set warning threshold for device policy package status. -Can used special variables like: %{status}, %{package_name} +You can use the following variables: %{status}, %{package_name} =item B<--critical-device-policy-package-status> Set critical threshold for device policy package status. -Can used special variables like: %{status}, %{package_name} +You can use the following variables: %{status}, %{package_name} =back diff --git a/src/network/fortinet/fortiswitch/snmp/mode/interfaces.pm b/src/network/fortinet/fortiswitch/snmp/mode/interfaces.pm index a524cdeee..20e51b21c 100644 --- a/src/network/fortinet/fortiswitch/snmp/mode/interfaces.pm +++ b/src/network/fortinet/fortiswitch/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/fortinet/fortiweb/snmp/mode/system.pm b/src/network/fortinet/fortiweb/snmp/mode/system.pm index d7713daf2..b41817641 100644 --- a/src/network/fortinet/fortiweb/snmp/mode/system.pm +++ b/src/network/fortinet/fortiweb/snmp/mode/system.pm @@ -156,12 +156,12 @@ Example: --filter-counters='memory-usage' =item B<--warning-ha-status> Set warning threshold for status. -Can used special variables like: %{ha_mode} +You can use the following variables: %{ha_mode} =item B<--critical-ha-status> Set critical threshold for status. -Can used special variables like: %{ha_mode} +You can use the following variables: %{ha_mode} =item B<--warning-*> B<--critical-*> diff --git a/src/network/freebox/restapi/mode/system.pm b/src/network/freebox/restapi/mode/system.pm index 09ced9c98..9a8533949 100644 --- a/src/network/freebox/restapi/mode/system.pm +++ b/src/network/freebox/restapi/mode/system.pm @@ -183,22 +183,22 @@ Example: --filter-counters='^temperature-cpum$' =item B<--warning-wifi-status> Set warning threshold for wifi status (Default: '%{status} =~ /bad_param/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-wifi-status> Set critical threshold for wifi status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-disk-status> Set warning threshold for disk status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-disk-status> Set critical threshold for disk status (Default: '%{status} =~ /error/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/hirschmann/standard/snmp/mode/configuration.pm b/src/network/hirschmann/standard/snmp/mode/configuration.pm index e56b04ef8..768f1c218 100644 --- a/src/network/hirschmann/standard/snmp/mode/configuration.pm +++ b/src/network/hirschmann/standard/snmp/mode/configuration.pm @@ -114,12 +114,12 @@ Check configuration status. =item B<--warning-status> Set warning threshold for status (Default : '%{config_status} =~ /notInSync|outOfSync/'). -Can used special variables like: %{config_status} +You can use the following variables: %{config_status} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{config_status} +You can use the following variables: %{config_status} =back diff --git a/src/network/hp/moonshot/snmp/mode/interfaces.pm b/src/network/hp/moonshot/snmp/mode/interfaces.pm index 1d0cfb4c3..ede98bcaf 100644 --- a/src/network/hp/moonshot/snmp/mode/interfaces.pm +++ b/src/network/hp/moonshot/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/hp/procurve/snmp/mode/interfaces.pm b/src/network/hp/procurve/snmp/mode/interfaces.pm index 65d2efbc8..9d16af011 100644 --- a/src/network/hp/procurve/snmp/mode/interfaces.pm +++ b/src/network/hp/procurve/snmp/mode/interfaces.pm @@ -303,22 +303,22 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-poe-status> Set warning threshold for poe status. -Can used special variables like: %{admstatus}, %{opstatus}, %{poestatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{poestatus}, %{display} =item B<--critical-poe-status> Set critical threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{poestatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{poestatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/hp/procurve/snmp/mode/virtualchassis.pm b/src/network/hp/procurve/snmp/mode/virtualchassis.pm index a1964dec7..11595c4dd 100644 --- a/src/network/hp/procurve/snmp/mode/virtualchassis.pm +++ b/src/network/hp/procurve/snmp/mode/virtualchassis.pm @@ -324,47 +324,47 @@ Filter members by serial (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /active/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-member-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{stateLast} +You can use the following variables: %{state}, %{stateLast} =item B<--warning-member-status> Set warning threshold for status. -Can used special variables like: %{state}, %{stateLast} +You can use the following variables: %{state}, %{stateLast} =item B<--critical-member-status> Set critical threshold for status (Default: '%{state} ne %{stateLast} || %{state} =~ /communicationFailure|incompatibleOS/i'). -Can used special variables like: %{state}, %{stateLast} +You can use the following variables: %{state}, %{stateLast} =item B<--unknown-link-status> Set unknown threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-link-status> Set warning threshold for status. -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--critical-link-status> Set critical threshold for status (Default: '%{link_status} eq "down"'). -Can used special variables like: %{link_status}, %{display} +You can use the following variables: %{link_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/huawei/snmp/mode/interfaces.pm b/src/network/huawei/snmp/mode/interfaces.pm index 8729c9be0..2cdd2db30 100644 --- a/src/network/huawei/snmp/mode/interfaces.pm +++ b/src/network/huawei/snmp/mode/interfaces.pm @@ -214,12 +214,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-errors> diff --git a/src/network/infoblox/snmp/mode/system.pm b/src/network/infoblox/snmp/mode/system.pm index d33a0f2b8..e0ebfc8e6 100644 --- a/src/network/infoblox/snmp/mode/system.pm +++ b/src/network/infoblox/snmp/mode/system.pm @@ -186,12 +186,12 @@ Example: --filter-counters='^memory-usage$' =item B<--warning-ha-status> Set warning threshold for status. -Can used special variables like: %{ha_status} +You can use the following variables: %{ha_status} =item B<--critical-ha-status> Set critical threshold for status. -Can used special variables like: %{ha_status} +You can use the following variables: %{ha_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/juniper/common/junos/mode/interfaces.pm b/src/network/juniper/common/junos/mode/interfaces.pm index 1e0ecd9ba..58567110f 100644 --- a/src/network/juniper/common/junos/mode/interfaces.pm +++ b/src/network/juniper/common/junos/mode/interfaces.pm @@ -289,12 +289,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-errors> diff --git a/src/network/juniper/common/junos/mode/ipsectunnel.pm b/src/network/juniper/common/junos/mode/ipsectunnel.pm index 1faaab6c8..9676c3634 100644 --- a/src/network/juniper/common/junos/mode/ipsectunnel.pm +++ b/src/network/juniper/common/junos/mode/ipsectunnel.pm @@ -249,17 +249,17 @@ Example: --filter-counters='tunnels-total' =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{ike_state}, %{display} +You can use the following variables: %{ike_state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{ike_state}, %{display} +You can use the following variables: %{ike_state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{ike_state} eq "down"'). -Can used special variables like: %{ike_state}, %{display} +You can use the following variables: %{ike_state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/juniper/common/junos/mode/ldpsessionstatus.pm b/src/network/juniper/common/junos/mode/ldpsessionstatus.pm index bf5471da2..c19203c7d 100644 --- a/src/network/juniper/common/junos/mode/ldpsessionstatus.pm +++ b/src/network/juniper/common/junos/mode/ldpsessionstatus.pm @@ -176,12 +176,12 @@ Can be: 'entity', 'peer' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /operational/i'). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--warning-last-change> diff --git a/src/network/juniper/common/junos/mode/lspstatus.pm b/src/network/juniper/common/junos/mode/lspstatus.pm index 21bf1aff4..4de891083 100644 --- a/src/network/juniper/common/junos/mode/lspstatus.pm +++ b/src/network/juniper/common/junos/mode/lspstatus.pm @@ -197,12 +197,12 @@ Can be: 'name', 'from', 'to' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /up/i'). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--warning-*> diff --git a/src/network/juniper/common/junos/mode/rsvpsessionstatus.pm b/src/network/juniper/common/junos/mode/rsvpsessionstatus.pm index 1347cd464..4bde77f77 100644 --- a/src/network/juniper/common/junos/mode/rsvpsessionstatus.pm +++ b/src/network/juniper/common/junos/mode/rsvpsessionstatus.pm @@ -170,12 +170,12 @@ Can be: 'name', 'from', 'to' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /up/i'). -Can used special variables like: %{state} +You can use the following variables: %{state} =back diff --git a/src/network/juniper/common/junos/mode/stack.pm b/src/network/juniper/common/junos/mode/stack.pm index 86e355483..b2e4c8ad2 100644 --- a/src/network/juniper/common/junos/mode/stack.pm +++ b/src/network/juniper/common/junos/mode/stack.pm @@ -214,32 +214,32 @@ Check stack members. =item B<--unknown-member-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{role}, %{roleLast} +You can use the following variables: %{role}, %{roleLast} =item B<--warning-member-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{role}, %{roleLast} +You can use the following variables: %{role}, %{roleLast} =item B<--critical-member-status> Set critical threshold for status (Default: '%{role} ne %{roleLast}'). -Can used special variables like: %{role}, %{roleLast} +You can use the following variables: %{role}, %{roleLast} =item B<--unknown-port-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{admin_status}, %{oper_status}, %{display} +You can use the following variables: %{admin_status}, %{oper_status}, %{display} =item B<--warning-port-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{admin_status}, %{oper_status}, %{display} +You can use the following variables: %{admin_status}, %{oper_status}, %{display} =item B<--critical-port-status> Set critical threshold for status (Default: '%{admin_status} eq "up" and %{oper_status} ne "up"'). -Can used special variables like: %{admin_status}, %{oper_status}, %{display} +You can use the following variables: %{admin_status}, %{oper_status}, %{display} =back diff --git a/src/network/juniper/common/screenos/snmp/mode/nsrp.pm b/src/network/juniper/common/screenos/snmp/mode/nsrp.pm index 0edc4e20f..d99071f9a 100644 --- a/src/network/juniper/common/screenos/snmp/mode/nsrp.pm +++ b/src/network/juniper/common/screenos/snmp/mode/nsrp.pm @@ -186,17 +186,17 @@ Check nsrp groups. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /undefined/i'). -Can used special variables like: %{status}, %{statusLast} +You can use the following variables: %{status}, %{statusLast} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{statusLast} +You can use the following variables: %{status}, %{statusLast} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /ineligible|inoperable/i'). -Can used special variables like: %{status}, %{statusLast} +You can use the following variables: %{status}, %{statusLast} =item B<--warning-*> B<--critical-*> diff --git a/src/network/juniper/common/screenos/snmp/mode/vpnstatus.pm b/src/network/juniper/common/screenos/snmp/mode/vpnstatus.pm index 1969b2bb4..14fb53438 100644 --- a/src/network/juniper/common/screenos/snmp/mode/vpnstatus.pm +++ b/src/network/juniper/common/screenos/snmp/mode/vpnstatus.pm @@ -166,12 +166,12 @@ Filter VPN name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{p1state}, %{p2state} +You can use the following variables: %{p1state}, %{p2state} =item B<--critical-status> Set critical threshold for status (Default: '%{p1state} eq "inactive" || %{p2state} eq "inactive"'). -Can used special variables like: %{p1state}, %{p2state} +You can use the following variables: %{p1state}, %{p2state} =item B<--warning-update-time> diff --git a/src/network/juniper/trapeze/snmp/mode/apstatus.pm b/src/network/juniper/trapeze/snmp/mode/apstatus.pm index 378158ba4..6fd68494a 100644 --- a/src/network/juniper/trapeze/snmp/mode/apstatus.pm +++ b/src/network/juniper/trapeze/snmp/mode/apstatus.pm @@ -178,12 +178,12 @@ Filter AP name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{opstatus}, %{display} +You can use the following variables: %{opstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{opstatus} !~ /init|redundant|operationnal/'). -Can used special variables like: %{opstatus}, %{display} +You can use the following variables: %{opstatus}, %{display} =item B<--warning-total> diff --git a/src/network/kemp/snmp/mode/hastatus.pm b/src/network/kemp/snmp/mode/hastatus.pm index 9ac6584bb..8c0084710 100644 --- a/src/network/kemp/snmp/mode/hastatus.pm +++ b/src/network/kemp/snmp/mode/hastatus.pm @@ -151,22 +151,22 @@ Example: --filter-counters='^ha-status$' =item B<--warning-ha-status> Set warning threshold for status (Default: none). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-ha-status> Set critical threshold for status (Default: none). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-sync-status> Set warning threshold for status (Default: none). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-sync-status> Set critical threshold for status (Default: none). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/network/kemp/snmp/mode/rsstatus.pm b/src/network/kemp/snmp/mode/rsstatus.pm index 01a175859..eac863f29 100644 --- a/src/network/kemp/snmp/mode/rsstatus.pm +++ b/src/network/kemp/snmp/mode/rsstatus.pm @@ -191,12 +191,12 @@ Filter real server name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /inService|disabled/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/kemp/snmp/mode/vsstatus.pm b/src/network/kemp/snmp/mode/vsstatus.pm index 644ee15d9..616c1dfff 100644 --- a/src/network/kemp/snmp/mode/vsstatus.pm +++ b/src/network/kemp/snmp/mode/vsstatus.pm @@ -189,12 +189,12 @@ Filter virtual server name (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /inService|disabled|redirect/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/keysight/nvos/restapi/mode/hardware.pm b/src/network/keysight/nvos/restapi/mode/hardware.pm index a533c82ce..17e5e8237 100644 --- a/src/network/keysight/nvos/restapi/mode/hardware.pm +++ b/src/network/keysight/nvos/restapi/mode/hardware.pm @@ -163,32 +163,32 @@ Check hardware. =item B<--unknown-temperature-status> Set unknown threshold for status (Default : '%{status} eq "unknown"'). -Can used special variables like: %{status}, %{class} +You can use the following variables: %{status}, %{class} =item B<--warning-temperature-status> Set warning threshold for status (Default : '%{status} eq "warn"'). -Can used special variables like: %{status}, %{class} +You can use the following variables: %{status}, %{class} =item B<--critical-temperature-status> Set critical threshold for status (Default: '%{status} eq "hot"'); -Can used special variables like: %{status}, %{class} +You can use the following variables: %{status}, %{class} =item B<--unknown-psu-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-psu-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "bad"'); -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/keysight/nvos/restapi/mode/ports.pm b/src/network/keysight/nvos/restapi/mode/ports.pm index b85b3f691..cb294c16e 100644 --- a/src/network/keysight/nvos/restapi/mode/ports.pm +++ b/src/network/keysight/nvos/restapi/mode/ports.pm @@ -253,32 +253,32 @@ Filter ports by name (can be a regexp). =item B<--unknown-license-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-license-status> Set warning threshold for status (Default: '%{status} =~ /invalid_software_version/'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-license-status> Set critical threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-link-status> Set unknown threshold for status. -Can used special variables like: %{adminStatus}, %{operationalStatus}, %{name} +You can use the following variables: %{adminStatus}, %{operationalStatus}, %{name} =item B<--warning-link-status> Set warning threshold for status. -Can used special variables like: %{adminStatus}, %{operationalStatus}, %{name} +You can use the following variables: %{adminStatus}, %{operationalStatus}, %{name} =item B<--critical-link-status> Set critical threshold for status (Default: '%{adminStatus} eq "enabled" and %{operationalStatus} ne "up"'). -Can used special variables like: %{adminStatus}, %{operationalStatus}, %{name} +You can use the following variables: %{adminStatus}, %{operationalStatus}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/keysight/nvos/restapi/mode/time.pm b/src/network/keysight/nvos/restapi/mode/time.pm index 44c077e9e..6cd7e3d01 100644 --- a/src/network/keysight/nvos/restapi/mode/time.pm +++ b/src/network/keysight/nvos/restapi/mode/time.pm @@ -165,7 +165,7 @@ Check time offset of server with ntp server. Use local time if ntp-host option i Set thresholds for status (Default critical: '%{status} !~ /in_reach|in_sync/i') -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-offset> diff --git a/src/network/lenovo/rackswitch/snmp/mode/hardware.pm b/src/network/lenovo/rackswitch/snmp/mode/hardware.pm index 124ee99ed..0e327f6e8 100644 --- a/src/network/lenovo/rackswitch/snmp/mode/hardware.pm +++ b/src/network/lenovo/rackswitch/snmp/mode/hardware.pm @@ -137,17 +137,17 @@ Check hardware. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} eq "noncritical"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "critical"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/lenovo/rackswitch/snmp/mode/interfaces.pm b/src/network/lenovo/rackswitch/snmp/mode/interfaces.pm index 9c0c6ecef..f62f8373d 100644 --- a/src/network/lenovo/rackswitch/snmp/mode/interfaces.pm +++ b/src/network/lenovo/rackswitch/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/libraesva/snmp/mode/interfaces.pm b/src/network/libraesva/snmp/mode/interfaces.pm index 1cb34424d..c7050310a 100644 --- a/src/network/libraesva/snmp/mode/interfaces.pm +++ b/src/network/libraesva/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/libraesva/snmp/mode/system.pm b/src/network/libraesva/snmp/mode/system.pm index 24398552d..b3d801b66 100644 --- a/src/network/libraesva/snmp/mode/system.pm +++ b/src/network/libraesva/snmp/mode/system.pm @@ -172,17 +172,17 @@ Example: --filter-counters='^mail-sent$' =item B<--unknown-cluster-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{cluster_status} +You can use the following variables: %{cluster_status} =item B<--warning-cluster-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{cluster_status} +You can use the following variables: %{cluster_status} =item B<--critical-cluster-status> Set critical threshold for status (Default: '%{cluster_status} =~ /error/i'). -Can used special variables like: %{cluster_status} +You can use the following variables: %{cluster_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/microsens/g6/snmp/mode/interfaces.pm b/src/network/microsens/g6/snmp/mode/interfaces.pm index 1b9b7c82c..972c6aa36 100644 --- a/src/network/microsens/g6/snmp/mode/interfaces.pm +++ b/src/network/microsens/g6/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/microsens/g6/snmp/mode/sfp.pm b/src/network/microsens/g6/snmp/mode/sfp.pm index 188246f14..0bbc0c24c 100644 --- a/src/network/microsens/g6/snmp/mode/sfp.pm +++ b/src/network/microsens/g6/snmp/mode/sfp.pm @@ -198,12 +198,12 @@ Filter ports by index (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{location} +You can use the following variables: %{status}, %{name}, %{location} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /txFailure|lossOfSignal|readError/'). -Can used special variables like: %{status}, %{port}, %{location} +You can use the following variables: %{status}, %{port}, %{location} =item B<--warning-*> B<--critical-*> diff --git a/src/network/mikrotik/snmp/mode/firmware.pm b/src/network/mikrotik/snmp/mode/firmware.pm index 9f1831fc9..fa277e5c2 100644 --- a/src/network/mikrotik/snmp/mode/firmware.pm +++ b/src/network/mikrotik/snmp/mode/firmware.pm @@ -101,12 +101,12 @@ Check firmware status. =item B<--warning-status> Set warning threshold for status (Default : '%{firmware_version} ne %{software_version}'). -Can used special variables like: %{model}, %{software_version}, %{firmware_version}, %{firmware_version_update} +You can use the following variables: %{model}, %{software_version}, %{firmware_version}, %{firmware_version_update} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{model}, %{software_version}, %{firmware_version}, %{firmware_version_update} +You can use the following variables: %{model}, %{software_version}, %{firmware_version}, %{firmware_version_update} =back diff --git a/src/network/mikrotik/snmp/mode/interfaces.pm b/src/network/mikrotik/snmp/mode/interfaces.pm index f4231e922..0a955428d 100644 --- a/src/network/mikrotik/snmp/mode/interfaces.pm +++ b/src/network/mikrotik/snmp/mode/interfaces.pm @@ -180,12 +180,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-errors> diff --git a/src/network/mrv/optiswitch/snmp/mode/interfaces.pm b/src/network/mrv/optiswitch/snmp/mode/interfaces.pm index 68e667616..940e83ae7 100644 --- a/src/network/mrv/optiswitch/snmp/mode/interfaces.pm +++ b/src/network/mrv/optiswitch/snmp/mode/interfaces.pm @@ -463,12 +463,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "enable =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{linkstatus}, %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{linkstatus}, %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "enable" and %{opstatus} eq "enabled" and %{linkstatus} ne "true"'). -Can used special variables like: %{linkstatus}, %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{linkstatus}, %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/netgear/sseries/snmp/mode/interfaces.pm b/src/network/netgear/sseries/snmp/mode/interfaces.pm index d1a1016fb..6691677da 100644 --- a/src/network/netgear/sseries/snmp/mode/interfaces.pm +++ b/src/network/netgear/sseries/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/nokia/timos/snmp/mode/bgpusage.pm b/src/network/nokia/timos/snmp/mode/bgpusage.pm index 5f22f8cf7..9df68ad9b 100644 --- a/src/network/nokia/timos/snmp/mode/bgpusage.pm +++ b/src/network/nokia/timos/snmp/mode/bgpusage.pm @@ -203,12 +203,12 @@ Can be: 'active-prefixes', 'sent-prefixes', 'received-prefixes'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{state} +You can use the following variables: %{display}, %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /outOfService/') -Can used special variables like: %{display}, %{state} +You can use the following variables: %{display}, %{state} =item B<--filter-name> diff --git a/src/network/nokia/timos/snmp/mode/isisusage.pm b/src/network/nokia/timos/snmp/mode/isisusage.pm index 3c980c99a..dc3adb676 100644 --- a/src/network/nokia/timos/snmp/mode/isisusage.pm +++ b/src/network/nokia/timos/snmp/mode/isisusage.pm @@ -212,12 +212,12 @@ Can be: 'total-int-inservice', 'total-int-outservice'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{oper_state}, %{admin_state}. +You can use the following variables: %{display}, %{oper_state}, %{admin_state}. =item B<--critical-status> Set critical threshold for status (Default: '%{admin_state} eq "inService" and %{oper_state} !~ /inService|transition/'). -Can used special variables like: %{display}, %{oper_state}, %{admin_state}. +You can use the following variables: %{display}, %{oper_state}, %{admin_state}. =item B<--filter-name> diff --git a/src/network/nokia/timos/snmp/mode/l2tpusage.pm b/src/network/nokia/timos/snmp/mode/l2tpusage.pm index 85355cfef..9adea3f3f 100644 --- a/src/network/nokia/timos/snmp/mode/l2tpusage.pm +++ b/src/network/nokia/timos/snmp/mode/l2tpusage.pm @@ -299,12 +299,12 @@ Can be: 'vrtr-tunnel-total', 'vrtr-tunnel-active-sessions', 'vrtr-tunnel-total-s =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{state} +You can use the following variables: %{display}, %{state} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{display}, %{state} +You can use the following variables: %{display}, %{state} =item B<--filter-vrtr-name> diff --git a/src/network/nokia/timos/snmp/mode/ldpusage.pm b/src/network/nokia/timos/snmp/mode/ldpusage.pm index 487a688ab..54fd1a2d8 100644 --- a/src/network/nokia/timos/snmp/mode/ldpusage.pm +++ b/src/network/nokia/timos/snmp/mode/ldpusage.pm @@ -223,12 +223,12 @@ Can be: 'ipv4-oper-down-events', 'ipv4-active-sessions', 'ipv4-active-link-adj', =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{ipv4_oper_state}, %{admin_state}, %{display} +You can use the following variables: %{ipv4_oper_state}, %{admin_state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admin_state} eq "inService" and %{ipv4_oper_state} !~ /inService|transition/'). -Can used special variables like: %{ipv4_oper_state}, %{admin_state}, %{display} +You can use the following variables: %{ipv4_oper_state}, %{admin_state}, %{display} =item B<--filter-name> diff --git a/src/network/nokia/timos/snmp/mode/sapusage.pm b/src/network/nokia/timos/snmp/mode/sapusage.pm index 1a39082c7..febaa64d8 100644 --- a/src/network/nokia/timos/snmp/mode/sapusage.pm +++ b/src/network/nokia/timos/snmp/mode/sapusage.pm @@ -218,12 +218,12 @@ Check service access point usage. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admin_state} eq "up" and %{oper_state} !~ /up/'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/nortel/standard/snmp/mode/interfaces.pm b/src/network/nortel/standard/snmp/mode/interfaces.pm index 5a683c2fd..8c44ab99f 100644 --- a/src/network/nortel/standard/snmp/mode/interfaces.pm +++ b/src/network/nortel/standard/snmp/mode/interfaces.pm @@ -104,12 +104,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/nortel/standard/snmp/mode/stack.pm b/src/network/nortel/standard/snmp/mode/stack.pm index 3a87f0955..e87a91a49 100644 --- a/src/network/nortel/standard/snmp/mode/stack.pm +++ b/src/network/nortel/standard/snmp/mode/stack.pm @@ -218,17 +218,17 @@ Check stack units. =item B<--unknown-unit-status> Set unknown threshold for status. -Can used special variables like: %{operState}, %{adminState}, %{serial} +You can use the following variables: %{operState}, %{adminState}, %{serial} =item B<--warning-unit-status> Set warning threshold for status (Default: '%{adminState} eq "enable" && %{operState} =~ /nonFatalErr|warning/i'). -Can used special variables like: %{operState}, %{adminState}, %{serial} +You can use the following variables: %{operState}, %{adminState}, %{serial} =item B<--critical-unit-status> Set critical threshold for status (Default: '%{adminState} eq "enable" && %{operState} =~ /fatalErr/i'). -Can used special variables like: %{operState}, %{adminState}, %{serial} +You can use the following variables: %{operState}, %{adminState}, %{serial} =item B<--unit> diff --git a/src/network/oneaccess/snmp/mode/cellsradio.pm b/src/network/oneaccess/snmp/mode/cellsradio.pm index aa3fe1c33..5fb1e3d4b 100644 --- a/src/network/oneaccess/snmp/mode/cellsradio.pm +++ b/src/network/oneaccess/snmp/mode/cellsradio.pm @@ -295,17 +295,17 @@ Filter cell modules by id (IMEI or MEID). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{simStatus}, %{signalQuality}, %{cellId}, %{operator}, %{imsi} +You can use the following variables: %{simStatus}, %{signalQuality}, %{cellId}, %{operator}, %{imsi} =item B<--warning-status> Set warning threshold for status (Default: '%{signalQuality} =~ /poor/'). -Can used special variables like: %{simStatus}, %{signalQuality}, %{cellId}, %{operator}, %{imsi} +You can use the following variables: %{simStatus}, %{signalQuality}, %{cellId}, %{operator}, %{imsi} =item B<--critical-status> Set critical threshold for status (Default: '%{simStatus} eq "notPresent" || %{signalQuality} =~ /none/'). -Can used special variables like: %{simStatus}, %{signalQuality}, %{cellId}, %{operator}, %{imsi} +You can use the following variables: %{simStatus}, %{signalQuality}, %{cellId}, %{operator}, %{imsi} =item B<--warning-*> B<--critical-*> diff --git a/src/network/oneaccess/snmp/mode/interfaces.pm b/src/network/oneaccess/snmp/mode/interfaces.pm index 021a2d696..ca1b3ef2b 100644 --- a/src/network/oneaccess/snmp/mode/interfaces.pm +++ b/src/network/oneaccess/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/oneaccess/snmp/mode/rttprobes.pm b/src/network/oneaccess/snmp/mode/rttprobes.pm index adeee9b0a..58106be5a 100644 --- a/src/network/oneaccess/snmp/mode/rttprobes.pm +++ b/src/network/oneaccess/snmp/mode/rttprobes.pm @@ -191,17 +191,17 @@ Filter probes by name. =item B<--unknown-probe-status> Set unknown threshold for status. -Can used special variables like: %{adminStatus}, %{status}, %{type}, %{tag} +You can use the following variables: %{adminStatus}, %{status}, %{type}, %{tag} =item B<--warning-probe-estatus> Set warning threshold for status. -Can used special variables like: %{adminStatus}, %{status}, %{type}, %{tag} +You can use the following variables: %{adminStatus}, %{status}, %{type}, %{tag} =item B<--critical-probe-status> Set critical threshold for status (Default: '%{adminStatus} eq "active" and %{status} ne "ok"'). -Can used special variables like: %{adminStatus}, %{status}, %{type}, %{tag} +You can use the following variables: %{adminStatus}, %{status}, %{type}, %{tag} =item B<--warning-*> B<--critical-*> diff --git a/src/network/opengear/snmp/mode/interfaces.pm b/src/network/opengear/snmp/mode/interfaces.pm index e2c9da614..c99887a02 100644 --- a/src/network/opengear/snmp/mode/interfaces.pm +++ b/src/network/opengear/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/oracle/infiniband/snmp/mode/infinibandusage.pm b/src/network/oracle/infiniband/snmp/mode/infinibandusage.pm index e3eb48cc3..ebe25c97f 100644 --- a/src/network/oracle/infiniband/snmp/mode/infinibandusage.pm +++ b/src/network/oracle/infiniband/snmp/mode/infinibandusage.pm @@ -345,12 +345,12 @@ Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). =item B<--warning-ib-status> Set warning threshold for ib status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-ib-status> Set critical threshold for ib status (Default: '%{status} !~ /up/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/network/paloalto/snmp/mode/panorama.pm b/src/network/paloalto/snmp/mode/panorama.pm index 046af622f..c3152e5de 100644 --- a/src/network/paloalto/snmp/mode/panorama.pm +++ b/src/network/paloalto/snmp/mode/panorama.pm @@ -112,12 +112,12 @@ Check panorama connection status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /not-connected/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =back diff --git a/src/network/paloalto/ssh/mode/interfaces.pm b/src/network/paloalto/ssh/mode/interfaces.pm index 09ceaf486..308c2723a 100644 --- a/src/network/paloalto/ssh/mode/interfaces.pm +++ b/src/network/paloalto/ssh/mode/interfaces.pm @@ -132,17 +132,17 @@ Filter interface name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{type}, %{ha_state}, %{display} +You can use the following variables: %{state}, %{type}, %{ha_state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{type}, %{ha_state}, %{display} +You can use the following variables: %{state}, %{type}, %{ha_state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "active"'). -Can used special variables like: %{state}, %{type}, %{ha_state}, %{display} +You can use the following variables: %{state}, %{type}, %{ha_state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/paloalto/ssh/mode/ipsec.pm b/src/network/paloalto/ssh/mode/ipsec.pm index 5958dad28..f0e764003 100644 --- a/src/network/paloalto/ssh/mode/ipsec.pm +++ b/src/network/paloalto/ssh/mode/ipsec.pm @@ -150,17 +150,17 @@ Filter tunnels by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{ike_phase1_state}, %{state}, %{monitor_status}, %{display}. +You can use the following variables: %{ike_phase1_state}, %{state}, %{monitor_status}, %{display}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{ike_phase1_state}, %{state}, %{monitor_status}, %{display}. +You can use the following variables: %{ike_phase1_state}, %{state}, %{monitor_status}, %{display}. =item B<--critical-status> Set critical threshold for status (Default: '%{ike_phase1_state} eq "down" or %{state} ne "active"'). -Can used special variables like: %{ike_phase1_state}, %{state}, %{monitor_status}, %{display}. +You can use the following variables: %{ike_phase1_state}, %{state}, %{monitor_status}, %{display}. =item B<--warning-*> B<--critical-*> diff --git a/src/network/paloalto/ssh/mode/system.pm b/src/network/paloalto/ssh/mode/system.pm index 7fce52b20..183c66e7f 100644 --- a/src/network/paloalto/ssh/mode/system.pm +++ b/src/network/paloalto/ssh/mode/system.pm @@ -258,12 +258,12 @@ Timezone options. Default is 'GMT'. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{oper_mode} +You can use the following variables: %{oper_mode} =item B<--critical-status> Set critical threshold for status (Default: '%{oper_mode} !~ /normal/i'). -Can used special variables like: %{oper_mode} +You can use the following variables: %{oper_mode} =item B<--warning-*> B<--critical-*> diff --git a/src/network/peplink/pepwave/snmp/mode/wanusage.pm b/src/network/peplink/pepwave/snmp/mode/wanusage.pm index 4961fd19f..45385ff7b 100644 --- a/src/network/peplink/pepwave/snmp/mode/wanusage.pm +++ b/src/network/peplink/pepwave/snmp/mode/wanusage.pm @@ -196,12 +196,12 @@ Filter wan name (can be a regexp). =item B<--warning-health-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{health_status}, %{display} +You can use the following variables: %{health_status}, %{display} =item B<--critical-health-status> Set critical threshold for status (Default: '%{health_status} =~ /fail/'). -Can used special variables like: %{health_status}, %{display} +You can use the following variables: %{health_status}, %{display} =item B<--warning-*> diff --git a/src/network/perle/ids/snmp/mode/alarms.pm b/src/network/perle/ids/snmp/mode/alarms.pm index 2057ae381..4a7d27916 100644 --- a/src/network/perle/ids/snmp/mode/alarms.pm +++ b/src/network/perle/ids/snmp/mode/alarms.pm @@ -177,12 +177,12 @@ Filter by message (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor/i') -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--memory> diff --git a/src/network/rad/airmux/snmp/mode/alarms.pm b/src/network/rad/airmux/snmp/mode/alarms.pm index 246783335..7f89c115a 100644 --- a/src/network/rad/airmux/snmp/mode/alarms.pm +++ b/src/network/rad/airmux/snmp/mode/alarms.pm @@ -171,12 +171,12 @@ Filter by message (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--memory> diff --git a/src/network/radware/alteon/snmp/mode/vserverstatus.pm b/src/network/radware/alteon/snmp/mode/vserverstatus.pm index 90fe48e6d..63619f40a 100644 --- a/src/network/radware/alteon/snmp/mode/vserverstatus.pm +++ b/src/network/radware/alteon/snmp/mode/vserverstatus.pm @@ -206,12 +206,12 @@ Can be: 'traffic', 'total-sessions', 'current-sessions'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--filter-name> diff --git a/src/network/raisecom/snmp/mode/interfaces.pm b/src/network/raisecom/snmp/mode/interfaces.pm index 021d7b78e..00bbb4f75 100644 --- a/src/network/raisecom/snmp/mode/interfaces.pm +++ b/src/network/raisecom/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/ruckus/scg/snmp/mode/apstatus.pm b/src/network/ruckus/scg/snmp/mode/apstatus.pm index 9edbf406c..cdbe9bbd8 100644 --- a/src/network/ruckus/scg/snmp/mode/apstatus.pm +++ b/src/network/ruckus/scg/snmp/mode/apstatus.pm @@ -156,12 +156,12 @@ Filter by AP name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{configuration_status} !~ /^Up-to-date$/i'). -Can used special variables like: %{connection_status}, %{registration_status}, %{configuration_status}, %{display} +You can use the following variables: %{connection_status}, %{registration_status}, %{configuration_status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{connection_status} =~ /^Disconnect$/i'). -Can used special variables like: %{connection_status}, %{registration_status}, %{configuration_status}, %{display} +You can use the following variables: %{connection_status}, %{registration_status}, %{configuration_status}, %{display} =back diff --git a/src/network/ruckus/smartzone/snmp/mode/accesspoints.pm b/src/network/ruckus/smartzone/snmp/mode/accesspoints.pm index e08c49ee6..eba3318ca 100644 --- a/src/network/ruckus/smartzone/snmp/mode/accesspoints.pm +++ b/src/network/ruckus/smartzone/snmp/mode/accesspoints.pm @@ -221,17 +221,17 @@ Filter by access point name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{config_status}, %{connection_status}, %{registration_status} +You can use the following variables: %{config_status}, %{connection_status}, %{registration_status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{config_status}, %{connection_status}, %{registration_status} +You can use the following variables: %{config_status}, %{connection_status}, %{registration_status} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{config_status}, %{connection_status}, %{registration_status} +You can use the following variables: %{config_status}, %{connection_status}, %{registration_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/ruckus/zonedirector/snmp/mode/accesspoints.pm b/src/network/ruckus/zonedirector/snmp/mode/accesspoints.pm index 1859cf595..69f295892 100644 --- a/src/network/ruckus/zonedirector/snmp/mode/accesspoints.pm +++ b/src/network/ruckus/zonedirector/snmp/mode/accesspoints.pm @@ -303,17 +303,17 @@ Filter by access point name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{zd_connection_status} +You can use the following variables: %{zd_connection_status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{zd_connection_status} +You can use the following variables: %{zd_connection_status} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{zd_connection_status} +You can use the following variables: %{zd_connection_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/ruckus/zonedirector/snmp/mode/system.pm b/src/network/ruckus/zonedirector/snmp/mode/system.pm index 5ae574bb1..0e7ccea65 100644 --- a/src/network/ruckus/zonedirector/snmp/mode/system.pm +++ b/src/network/ruckus/zonedirector/snmp/mode/system.pm @@ -264,17 +264,17 @@ Check system. =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{system_status}, %{peer_connected_status} +You can use the following variables: %{system_status}, %{peer_connected_status} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{system_status}, %{peer_connected_status} +You can use the following variables: %{system_status}, %{peer_connected_status} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{system_status}, %{peer_connected_status} +You can use the following variables: %{system_status}, %{peer_connected_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/silverpeak/snmp/mode/alarms.pm b/src/network/silverpeak/snmp/mode/alarms.pm index 8b1567e26..369979236 100644 --- a/src/network/silverpeak/snmp/mode/alarms.pm +++ b/src/network/silverpeak/snmp/mode/alarms.pm @@ -206,12 +206,12 @@ Filter by message (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). -Can used special variables like: %{severity}, %{text}, %{source}, %{since} +You can use the following variables: %{severity}, %{text}, %{source}, %{since} =item B<--memory> diff --git a/src/network/sonus/sbc/snmp/mode/channels.pm b/src/network/sonus/sbc/snmp/mode/channels.pm index 7ea06b92c..7a32aff0d 100644 --- a/src/network/sonus/sbc/snmp/mode/channels.pm +++ b/src/network/sonus/sbc/snmp/mode/channels.pm @@ -378,12 +378,12 @@ Filter channels by channel id (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/sonus/sbc/snmp/mode/dspstats.pm b/src/network/sonus/sbc/snmp/mode/dspstats.pm index b6ce02f4c..11a21da98 100644 --- a/src/network/sonus/sbc/snmp/mode/dspstats.pm +++ b/src/network/sonus/sbc/snmp/mode/dspstats.pm @@ -136,12 +136,12 @@ Thresholds. Can be: 'cpu-utilization', 'channels-active'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} eq "down"'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =back diff --git a/src/network/sonus/sbc/snmp/mode/interfaces.pm b/src/network/sonus/sbc/snmp/mode/interfaces.pm index cd3656ac3..ee0e1251a 100644 --- a/src/network/sonus/sbc/snmp/mode/interfaces.pm +++ b/src/network/sonus/sbc/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/stonesoft/snmp/mode/clusterstate.pm b/src/network/stonesoft/snmp/mode/clusterstate.pm index 0a4612945..491e61e76 100644 --- a/src/network/stonesoft/snmp/mode/clusterstate.pm +++ b/src/network/stonesoft/snmp/mode/clusterstate.pm @@ -110,17 +110,17 @@ Check status of clustered node. =item B<--unknown-status> Set unknown threshold for status (Default: '%{node_status} =~ /unknown/i'). -Can used special variables like: %{node_status}, %{node_member_id}. +You can use the following variables: %{node_status}, %{node_member_id}. =item B<--warning-status> Set warning threshold for status (Default: '%{node_status} =~ /lockedOnline/i'). -Can used special variables like: %{node_status}, %{node_member_id}. +You can use the following variables: %{node_status}, %{node_member_id}. =item B<--critical-status> Set critical threshold for status (Default: '%{node_status} =~ /^(?:offline|goingOffline|lockedOffline|goingLockedOffline|standby|goingStandby)$/i'). -Can used special variables like: %{node_status}, %{node_member_id}. +You can use the following variables: %{node_status}, %{node_member_id}. =back diff --git a/src/network/stormshield/api/mode/ha.pm b/src/network/stormshield/api/mode/ha.pm index 3c2ac5c35..28130616e 100644 --- a/src/network/stormshield/api/mode/ha.pm +++ b/src/network/stormshield/api/mode/ha.pm @@ -222,47 +222,47 @@ Check high availability. =item B<--unknown-member-state> Set unknown threshold for status. -Can used special variables like: %{state}, %{name} +You can use the following variables: %{state}, %{name} =item B<--warning-member-state> Set warning threshold for status. -Can used special variables like: %{state}, %{name} +You can use the following variables: %{state}, %{name} =item B<--critical-member-state> Set critical threshold for status. -Can used special variables like: %{state}, %{name} +You can use the following variables: %{state}, %{name} =item B<--unknown-member-link-status> Set unknown threshold for status (Default: '%{linkStatus} =~ /unknown/i'). -Can used special variables like: %{linkStatus}, %{name} +You can use the following variables: %{linkStatus}, %{name} =item B<--warning-member-link-status> Set warning threshold for status. -Can used special variables like: %{linkStatus}, %{name} +You can use the following variables: %{linkStatus}, %{name} =item B<--critical-member-link-status> Set critical threshold for status (Default: '%{linkStatus} =~ /failed|failing/i'). -Can used special variables like: %{linkStatus}, %{name} +You can use the following variables: %{linkStatus}, %{name} =item B<--unknown-member-config> Set unknown threshold for status. -Can used special variables like: %{isConfigSync}, %{name} +You can use the following variables: %{isConfigSync}, %{name} =item B<--warning-member-config> Set warning threshold for status (Default: '%{isConfigSync} eq "no"'). -Can used special variables like: %{isConfigSync}, %{name} +You can use the following variables: %{isConfigSync}, %{name} =item B<--critical-member-config> Set critical threshold for status. -Can used special variables like: %{isConfigSync}, %{name} +You can use the following variables: %{isConfigSync}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/stormshield/api/mode/health.pm b/src/network/stormshield/api/mode/health.pm index 237948e00..486288a03 100644 --- a/src/network/stormshield/api/mode/health.pm +++ b/src/network/stormshield/api/mode/health.pm @@ -136,17 +136,17 @@ Filter by firewalls by serial (can be a regexp). =item B<--unknown-service-status> Set unknown threshold for status. -Can used special variables like: %{health}, %{service} +You can use the following variables: %{health}, %{service} =item B<--warning-service-status> Set warning threshold for status (Default: '%{health} =~ /minor/i'). -Can used special variables like: %{health}, %{service} +You can use the following variables: %{health}, %{service} =item B<--critical-service-status> Set critical threshold for status (Default: '%{health} =~ /major/i'). -Can used special variables like: %{health}, %{service} +You can use the following variables: %{health}, %{service} =back diff --git a/src/network/stormshield/api/mode/interfaces.pm b/src/network/stormshield/api/mode/interfaces.pm index 0192a655a..949267290 100644 --- a/src/network/stormshield/api/mode/interfaces.pm +++ b/src/network/stormshield/api/mode/interfaces.pm @@ -435,17 +435,17 @@ Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{plugged}, %{user_name}, %{real_name} +You can use the following variables: %{state}, %{plugged}, %{user_name}, %{real_name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{plugged}, %{user_name}, %{real_name} +You can use the following variables: %{state}, %{plugged}, %{user_name}, %{real_name} =item B<--critical-status> Set critical threshold for status (Default: "%{state} eq 'enabled' and %{plugged} eq 'unplugged'") -Can used special variables like: %{state}, %{plugged}, %{user_name}, %{real_name} +You can use the following variables: %{state}, %{plugged}, %{user_name}, %{real_name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/stormshield/snmp/mode/hanodes.pm b/src/network/stormshield/snmp/mode/hanodes.pm index d2c5898b7..c9f693881 100644 --- a/src/network/stormshield/snmp/mode/hanodes.pm +++ b/src/network/stormshield/snmp/mode/hanodes.pm @@ -239,12 +239,12 @@ Critical on deadnode (absolute unless --percent is used) =item B<--warning-state> Set warning threshold for state. -Can used special variables like: %{state}, %{role} +You can use the following variables: %{state}, %{role} =item B<--critical-state> Set critical threshold for state. (Default: '%{state} =~ /offline/i'). -Can used special variables like: %{state}, %{role} +You can use the following variables: %{state}, %{role} =item B<--percent> diff --git a/src/network/stormshield/snmp/mode/health.pm b/src/network/stormshield/snmp/mode/health.pm index 1424c7688..3182af885 100644 --- a/src/network/stormshield/snmp/mode/health.pm +++ b/src/network/stormshield/snmp/mode/health.pm @@ -172,17 +172,17 @@ Filter by firewall serial (can be a regexp). =item B<--unknown-service-status> Set unknown threshold for status. -Can used special variables like: %{health}, %{service} +You can use the following variables: %{health}, %{service} =item B<--warning-service-status> Set warning threshold for status (Default: '%{health} =~ /minor/i'). -Can used special variables like: %{health}, %{service} +You can use the following variables: %{health}, %{service} =item B<--critical-service-status> Set critical threshold for status (Default: '%{health} =~ /major/i'). -Can used special variables like: %{health}, %{service} +You can use the following variables: %{health}, %{service} =back diff --git a/src/network/stormshield/snmp/mode/vpnstatus.pm b/src/network/stormshield/snmp/mode/vpnstatus.pm index ae122de87..f0e2a42e3 100644 --- a/src/network/stormshield/snmp/mode/vpnstatus.pm +++ b/src/network/stormshield/snmp/mode/vpnstatus.pm @@ -251,17 +251,17 @@ Filter by dst ip (regexp can be used). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{srcIp}, %{dstIp} +You can use the following variables: %{state}, %{srcIp}, %{dstIp} =item B<--warning-status> Set warning threshold for status (Default: '%{state} eq "dead"'). -Can used special variables like: %{state}, %{srcIp}, %{dstIp} +You can use the following variables: %{state}, %{srcIp}, %{dstIp} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{srcIp}, %{dstIp} +You can use the following variables: %{state}, %{srcIp}, %{dstIp} =item B<--warning-*> B<--critical-*> diff --git a/src/network/teltonika/snmp/mode/system.pm b/src/network/teltonika/snmp/mode/system.pm index e11ce4734..6fb50c00f 100644 --- a/src/network/teltonika/snmp/mode/system.pm +++ b/src/network/teltonika/snmp/mode/system.pm @@ -184,12 +184,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{sim_state}, %{pin_state}, %{net_state}, %{connection_state} +You can use the following variables: %{sim_state}, %{pin_state}, %{net_state}, %{connection_state} =item B<--critical-status> Set critical threshold for status (Default: '%{connection_state} !~ /connected/i'). -Can used special variables like: %{sim_state}, %{pin_state}, %{net_state}, %{connection_state} +You can use the following variables: %{sim_state}, %{pin_state}, %{net_state}, %{connection_state} =item B<--warning-*> B<--critical-*> diff --git a/src/network/ubiquiti/airfiber/snmp/mode/radios.pm b/src/network/ubiquiti/airfiber/snmp/mode/radios.pm index cb4dd8562..2e2fc86d4 100644 --- a/src/network/ubiquiti/airfiber/snmp/mode/radios.pm +++ b/src/network/ubiquiti/airfiber/snmp/mode/radios.pm @@ -222,17 +222,17 @@ Filter interface by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{enabled}, %{state}, %{name} +You can use the following variables: %{enabled}, %{state}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{enabled}, %{state}, %{name} +You can use the following variables: %{enabled}, %{state}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{enabled} eq "yes" and %{state} eq "down"'). -Can used special variables like: %{enabled}, %{state}, %{name} +You can use the following variables: %{enabled}, %{state}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/ubiquiti/unifi/snmp/mode/virtualaccesspoints.pm b/src/network/ubiquiti/unifi/snmp/mode/virtualaccesspoints.pm index 9d8158350..57e66fc31 100644 --- a/src/network/ubiquiti/unifi/snmp/mode/virtualaccesspoints.pm +++ b/src/network/ubiquiti/unifi/snmp/mode/virtualaccesspoints.pm @@ -228,17 +228,17 @@ Filter virtual access points by SSID (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{name}, %{ssid}, %{status} +You can use the following variables: %{name}, %{ssid}, %{status} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{name}, %{ssid}, %{status} +You can use the following variables: %{name}, %{ssid}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "down"'). -Can used special variables like: %{name}, %{ssid}, %{status} +You can use the following variables: %{name}, %{ssid}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/ucopia/wlc/snmp/mode/system.pm b/src/network/ucopia/wlc/snmp/mode/system.pm index 5ebfe22cb..649895ecb 100644 --- a/src/network/ucopia/wlc/snmp/mode/system.pm +++ b/src/network/ucopia/wlc/snmp/mode/system.pm @@ -224,22 +224,22 @@ Example: --filter-counters='service-status' =item B<--warning-service-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-service-status> Set critical threshold for status (Default: '%{status} eq "stopped"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-ha-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{ha_status} +You can use the following variables: %{ha_status} =item B<--critical-ha-status> Set critical threshold for status (Default: '%{ha_status} eq "fault"'). -Can used special variables like: %{ha_status} +You can use the following variables: %{ha_status} =item B<--warning-*> B<--critical-*> diff --git a/src/network/vectra/restapi/mode/disk.pm b/src/network/vectra/restapi/mode/disk.pm index f4b84efa1..efac5d075 100644 --- a/src/network/vectra/restapi/mode/disk.pm +++ b/src/network/vectra/restapi/mode/disk.pm @@ -134,17 +134,17 @@ Check disks. =item B<--unknown-raid-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-raid-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-raid-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/vectra/restapi/mode/interfaces.pm b/src/network/vectra/restapi/mode/interfaces.pm index 84f9d128d..5f4474fc1 100644 --- a/src/network/vectra/restapi/mode/interfaces.pm +++ b/src/network/vectra/restapi/mode/interfaces.pm @@ -120,17 +120,17 @@ Filter interfaces by name (can be a regexp). =item B<--unknown-interface-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-interface-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-interface-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/vectra/restapi/mode/memory.pm b/src/network/vectra/restapi/mode/memory.pm index fafbdd25c..014eedfff 100644 --- a/src/network/vectra/restapi/mode/memory.pm +++ b/src/network/vectra/restapi/mode/memory.pm @@ -136,17 +136,17 @@ Check memory usage. =item B<--unknown-dimm-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-dimm-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-dimm-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/network/vectra/restapi/mode/sensors.pm b/src/network/vectra/restapi/mode/sensors.pm index 376f9e0b3..2dbda1767 100644 --- a/src/network/vectra/restapi/mode/sensors.pm +++ b/src/network/vectra/restapi/mode/sensors.pm @@ -205,62 +205,62 @@ Filter sensors by name (can be a regexp). =item B<--unknown-sensor-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-sensor-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-sensor-status> Set critical threshold for status (Default: '%{status} !~ /^paired/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-trafficdrop-status> Set warning threshold for status. -Can used special variables like: %{trafficDropStatus}, %{name} +You can use the following variables: %{trafficDropStatus}, %{name} =item B<--warning-trafficdrop-status> Set warning threshold for status (Default: '%{trafficDropStatus} =~ /warning|unknown|skip/i'). -Can used special variables like: %{trafficDropStatus}, %{name} +You can use the following variables: %{trafficDropStatus}, %{name} =item B<--critical-trafficdrop-status> Set critical threshold for status. -Can used special variables like: %{trafficDropStatus}, %{name} +You can use the following variables: %{trafficDropStatus}, %{name} =item B<--unknown-connectivity-status> Set warning threshold for status (Default: '%{connectivityStatus} =~ /unknown/i'). -Can used special variables like: %{connectivityStatus}, %{name} +You can use the following variables: %{connectivityStatus}, %{name} =item B<--warning-connectivity-status> Set warning threshold for status (Default: '%{connectivityStatus} =~ /warning/i'). -Can used special variables like: %{connectivityStatus}, %{name} +You can use the following variables: %{connectivityStatus}, %{name} =item B<--critical-connectivity-status> Set critical threshold for status (Default: '%{connectivityStatus} =~ /critical/i'). -Can used special variables like: %{connectivityStatus}, %{name} +You can use the following variables: %{connectivityStatus}, %{name} =item B<--unknown-interface-status> Set warning threshold for status. -Can used special variables like: %{status}, %{interfaceName}, %{sensorName} +You can use the following variables: %{status}, %{interfaceName}, %{sensorName} =item B<--warning-interface-status> Set warning threshold for status. -Can used special variables like: %{status}, %{interfaceName}, %{sensorName} +You can use the following variables: %{status}, %{interfaceName}, %{sensorName} =item B<--critical-interface-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{interfaceName}, %{sensorName} +You can use the following variables: %{status}, %{interfaceName}, %{sensorName} =item B<--warning-*> B<--critical-*> diff --git a/src/network/versa/director/restapi/mode/devices.pm b/src/network/versa/director/restapi/mode/devices.pm index 41b5e3752..c9e806957 100644 --- a/src/network/versa/director/restapi/mode/devices.pm +++ b/src/network/versa/director/restapi/mode/devices.pm @@ -498,17 +498,17 @@ Add path statuses count. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{ping_status}, %{services_status}, %{sync_status}, %{controller_status}, %{path_status}, %{display} +You can use the following variables: %{ping_status}, %{services_status}, %{sync_status}, %{controller_status}, %{path_status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{ping_status}, %{service_sstatus}, %{sync_status}, %{controller_status}, %{path_status}, %{display} +You can use the following variables: %{ping_status}, %{service_sstatus}, %{sync_status}, %{controller_status}, %{path_status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{ping_status} ne "reachable" or %{services_status} ne "good"'). -Can used special variables like: %{ping_status}, %{services_status}, %{sync_status}, %{controller_status}, %{path_status}, %{display} +You can use the following variables: %{ping_status}, %{services_status}, %{sync_status}, %{controller_status}, %{path_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/versa/snmp/mode/bgppeers.pm b/src/network/versa/snmp/mode/bgppeers.pm index b3c0d022c..941a1bbf6 100644 --- a/src/network/versa/snmp/mode/bgppeers.pm +++ b/src/network/versa/snmp/mode/bgppeers.pm @@ -205,17 +205,17 @@ Critical threshold on last update (seconds) =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{local_addr}, %{remote_addr}, %{as}, %{state}, %{display} +You can use the following variables: %{local_addr}, %{remote_addr}, %{as}, %{state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{local_addr}, %{remote_addr}, %{as}, %{state}, %{display} +You can use the following variables: %{local_addr}, %{remote_addr}, %{as}, %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /established/'). -Can used special variables like: %{local_addr}, %{remote_addr}, %{as}, %{state}, %{display} +You can use the following variables: %{local_addr}, %{remote_addr}, %{as}, %{state}, %{display} =back diff --git a/src/network/viptela/snmp/mode/controlconnections.pm b/src/network/viptela/snmp/mode/controlconnections.pm index 2dba53f62..73e169650 100644 --- a/src/network/viptela/snmp/mode/controlconnections.pm +++ b/src/network/viptela/snmp/mode/controlconnections.pm @@ -212,17 +212,17 @@ Filter connections by type. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{type}, %{privateIp}, %{publicIp} +You can use the following variables: %{status}, %{type}, %{privateIp}, %{publicIp} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{type}, %{privateIp}, %{publicIp} +You can use the following variables: %{status}, %{type}, %{privateIp}, %{publicIp} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /up|connect/'). -Can used special variables like: %{status}, %{type}, %{privateIp}, %{publicIp} +You can use the following variables: %{status}, %{type}, %{privateIp}, %{publicIp} =item B<--warning-*> B<--critical-*> diff --git a/src/network/viptela/snmp/mode/gretunnels.pm b/src/network/viptela/snmp/mode/gretunnels.pm index 39c133b32..7a96f8c39 100644 --- a/src/network/viptela/snmp/mode/gretunnels.pm +++ b/src/network/viptela/snmp/mode/gretunnels.pm @@ -276,17 +276,17 @@ Filter tunnels by destination ip address. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{adminState}, %{operState}, %{sourceIp}, %{destIp} +You can use the following variables: %{adminState}, %{operState}, %{sourceIp}, %{destIp} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{adminState}, %{operState}, %{sourceIp}, %{destIp} +You can use the following variables: %{adminState}, %{operState}, %{sourceIp}, %{destIp} =item B<--critical-status> Set critical threshold for status (Default: '%{adminState} eq "up" and %{operState} ne "up"'). -Can used special variables like: %{adminState}, %{operState}, %{sourceIp}, %{destIp} +You can use the following variables: %{adminState}, %{operState}, %{sourceIp}, %{destIp} =item B<--warning-*> B<--critical-*> diff --git a/src/network/viptela/snmp/mode/interfaces.pm b/src/network/viptela/snmp/mode/interfaces.pm index 7827a6f93..088b15447 100644 --- a/src/network/viptela/snmp/mode/interfaces.pm +++ b/src/network/viptela/snmp/mode/interfaces.pm @@ -82,12 +82,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/network/watchguard/snmp/mode/cluster.pm b/src/network/watchguard/snmp/mode/cluster.pm index d39c1cce9..3833d5203 100644 --- a/src/network/watchguard/snmp/mode/cluster.pm +++ b/src/network/watchguard/snmp/mode/cluster.pm @@ -162,32 +162,32 @@ Check cluster. =item B<--unknown-cluster-status> Set unknown threshold for status. -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--warning-cluster-status> Set warning threshold for status. -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--critical-cluster-status> Set critical threshold for status. -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--unknown-member-status> Set unknown threshold for status. -Can used special variables like: %{role}, %{serial} +You can use the following variables: %{role}, %{serial} =item B<--warning-member-status> Set warning threshold for status. -Can used special variables like: %{role}, %{serial} +You can use the following variables: %{role}, %{serial} =item B<--critical-member-status> Set critical threshold for status. -Can used special variables like: %{role}, %{serial} +You can use the following variables: %{role}, %{serial} =item B<--warning-*> B<--critical-*> diff --git a/src/network/zyxel/snmp/mode/vpnstatus.pm b/src/network/zyxel/snmp/mode/vpnstatus.pm index 93109bb9d..72e668f40 100644 --- a/src/network/zyxel/snmp/mode/vpnstatus.pm +++ b/src/network/zyxel/snmp/mode/vpnstatus.pm @@ -197,12 +197,12 @@ Can be: 'traffic-in', 'traffic-out'. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{activestatus}, %{connectstatus}, %{display} +You can use the following variables: %{activestatus}, %{connectstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{connectstatus} eq "disconnected"'). -Can used special variables like: %{activestatus}, %{connectstatus}, %{display} +You can use the following variables: %{activestatus}, %{connectstatus}, %{display} =back diff --git a/src/os/aix/local/mode/lvsync.pm b/src/os/aix/local/mode/lvsync.pm index 12aee1806..5b9ff0c66 100644 --- a/src/os/aix/local/mode/lvsync.pm +++ b/src/os/aix/local/mode/lvsync.pm @@ -146,17 +146,17 @@ Filter storage mount point (regexp can be used). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{lv}, %{mount}, %{type}. +You can use the following variables: %{state}, %{lv}, %{mount}, %{type}. =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{lv}, %{mount}, %{type}. +You can use the following variables: %{state}, %{lv}, %{mount}, %{type}. =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /stale/i'). -Can used special variables like: %{state}, %{lv}, %{mount}, %{type}. +You can use the following variables: %{state}, %{lv}, %{mount}, %{type}. =back diff --git a/src/os/aix/local/mode/process.pm b/src/os/aix/local/mode/process.pm index 3b9c8253b..a7148c1eb 100644 --- a/src/os/aix/local/mode/process.pm +++ b/src/os/aix/local/mode/process.pm @@ -205,12 +205,12 @@ You can use: 'Canceled', 'Nonexistent', 'Active', =item B<--warning-status> Set warning threshold for status (Default: '') -Can used special variables like: %{ppid}, %{state}, %{elapsed}, %{cmd}, %{args} +You can use the following variables: %{ppid}, %{state}, %{elapsed}, %{cmd}, %{args} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{ppid}, %{state}, %{elapsed}, %{cmd}, %{args} +You can use the following variables: %{ppid}, %{state}, %{elapsed}, %{cmd}, %{args} =item B<--warning-*> B<--critical-*> diff --git a/src/os/as400/connector/mode/command.pm b/src/os/as400/connector/mode/command.pm index 4dccecc24..1c19aca4f 100644 --- a/src/os/as400/connector/mode/command.pm +++ b/src/os/as400/connector/mode/command.pm @@ -116,17 +116,17 @@ Specify the command to execute (Required). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning--status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =back diff --git a/src/os/as400/connector/mode/disks.pm b/src/os/as400/connector/mode/disks.pm index 1c3e01709..a1b291346 100644 --- a/src/os/as400/connector/mode/disks.pm +++ b/src/os/as400/connector/mode/disks.pm @@ -241,17 +241,17 @@ Filter disks by name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning--status> Set warning threshold for status (Default: '%{status} =~ /noReady|busy|hwFailureOk|hwFailurePerf|Protected|rebuilding/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /^(noAccess|otherDiskSubFailed|failed|notOperational|noUnitControl)$/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/os/as400/connector/mode/jobqueues.pm b/src/os/as400/connector/mode/jobqueues.pm index 26ac1a6b1..4c2b8f6af 100644 --- a/src/os/as400/connector/mode/jobqueues.pm +++ b/src/os/as400/connector/mode/jobqueues.pm @@ -206,17 +206,17 @@ JOBQ selection. Eg: --jobq="QGPL:QBASE" --jobq="QGPL:QPGMR" =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name}, %{library} +You can use the following variables: %{status}, %{name}, %{library} =item B<--warning--status> Set warning threshold for status. -Can used special variables like: %{status}, %{name}, %{library} +You can use the following variables: %{status}, %{name}, %{library} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /HELD/i'). -Can used special variables like: %{status}, %{name}, %{library} +You can use the following variables: %{status}, %{name}, %{library} =item B<--warning-*> B<--critical-*> diff --git a/src/os/as400/connector/mode/subsystems.pm b/src/os/as400/connector/mode/subsystems.pm index e5b2f0f00..9f6d1bf63 100644 --- a/src/os/as400/connector/mode/subsystems.pm +++ b/src/os/as400/connector/mode/subsystems.pm @@ -188,17 +188,17 @@ Filter subsystems by library (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name}, %{library} +You can use the following variables: %{status}, %{name}, %{library} =item B<--warning--status> Set warning threshold for status (Default: '%{status} =~ /ending|restricted|starting/i'). -Can used special variables like: %{status}, %{name}, %{library} +You can use the following variables: %{status}, %{name}, %{library} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status}, %{name}, %{library} +You can use the following variables: %{status}, %{name}, %{library} =item B<--warning-*> B<--critical-*> diff --git a/src/os/linux/local/mode/checkplugin.pm b/src/os/linux/local/mode/checkplugin.pm index f2297fb87..cd94380c4 100644 --- a/src/os/linux/local/mode/checkplugin.pm +++ b/src/os/linux/local/mode/checkplugin.pm @@ -192,17 +192,17 @@ command to execute on the remote machine =item B<--unknown-status> Set unknown threshold for status (Default: '%{exit_code} == 3'). -Can used special variables like: %{short_message}, %{exit_code} +You can use the following variables: %{short_message}, %{exit_code} =item B<--warning-status> Set warning threshold for status (Default: '%{exit_code} == 1'). -Can used special variables like: %{short_message}, %{exit_code} +You can use the following variables: %{short_message}, %{exit_code} =item B<--critical-status> Set critical threshold for status (Default: '%{exit_code} == 2'). -Can used special variables like: %{short_message}, %{exit_code} +You can use the following variables: %{short_message}, %{exit_code} =item B<--warning-time> diff --git a/src/os/linux/local/mode/discoverysnmp.pm b/src/os/linux/local/mode/discoverysnmp.pm index dd5211659..1ea297988 100644 --- a/src/os/linux/local/mode/discoverysnmp.pm +++ b/src/os/linux/local/mode/discoverysnmp.pm @@ -219,11 +219,11 @@ Specify SNMP port (Default: 161). =item B<--snmp-version> -Specify SNMP version (Can be multiple) (Mandatory). +Specify SNMP version (can be defined multiple times) (Mandatory). =item B<--snmp-community> -Specify SNMP community (Can be multiple) (Mandatory). +Specify SNMP community (can be defined multiple times) (Mandatory). =item B<--snmp-timeout> diff --git a/src/os/linux/local/mode/discoverysnmpv3.pm b/src/os/linux/local/mode/discoverysnmpv3.pm index 6e3c00a80..22fd7608d 100644 --- a/src/os/linux/local/mode/discoverysnmpv3.pm +++ b/src/os/linux/local/mode/discoverysnmpv3.pm @@ -247,7 +247,7 @@ Resources discovery. Specify subnet from which discover resources (Must be / format) (Mandatory). -Specify SNMP community (Can be multiple) (Mandatory). +Specify SNMP community (can be defined multiple times) (Mandatory). =item B<--snmp-timeout> diff --git a/src/os/linux/local/mode/ntp.pm b/src/os/linux/local/mode/ntp.pm index 11a22df4c..f45bc4091 100644 --- a/src/os/linux/local/mode/ntp.pm +++ b/src/os/linux/local/mode/ntp.pm @@ -353,17 +353,17 @@ Threshold critical. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} +You can use the following variables: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} +You can use the following variables: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} +You can use the following variables: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} =back diff --git a/src/os/linux/local/mode/systemdscstatus.pm b/src/os/linux/local/mode/systemdscstatus.pm index 61ce68cef..87cf150df 100644 --- a/src/os/linux/local/mode/systemdscstatus.pm +++ b/src/os/linux/local/mode/systemdscstatus.pm @@ -189,12 +189,12 @@ Can be: 'total-running', 'total-dead', 'total-exited', =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{display}, %{active}, %{sub}, %{load}, %{boot} +You can use the following variables: %{display}, %{active}, %{sub}, %{load}, %{boot} =item B<--critical-status> Set critical threshold for status (Default: '%{active} =~ /failed/i'). -Can used special variables like: %{display}, %{active}, %{sub}, %{load}, %{boot} +You can use the following variables: %{display}, %{active}, %{sub}, %{load}, %{boot} =back diff --git a/src/os/linux/local/mode/traffic.pm b/src/os/linux/local/mode/traffic.pm index dac33da63..37d80be82 100644 --- a/src/os/linux/local/mode/traffic.pm +++ b/src/os/linux/local/mode/traffic.pm @@ -306,17 +306,17 @@ Threshold critical in percent for 'out' traffic. =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} ne "RU"'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--units> diff --git a/src/os/picos/snmp/mode/interfaces.pm b/src/os/picos/snmp/mode/interfaces.pm index 85e385f3a..db94a20b1 100644 --- a/src/os/picos/snmp/mode/interfaces.pm +++ b/src/os/picos/snmp/mode/interfaces.pm @@ -226,12 +226,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/os/windows/local/mode/pendingreboot.pm b/src/os/windows/local/mode/pendingreboot.pm index 792881908..be99c8485 100644 --- a/src/os/windows/local/mode/pendingreboot.pm +++ b/src/os/windows/local/mode/pendingreboot.pm @@ -199,13 +199,13 @@ Print powershell output. =item B<--warning-status> Set warning threshold for status (Default: '%{RebootPending} =~ /true/i'). -Can used special variables like: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, +You can use the following variables: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, %{PendFileRename}, %{PendComputerRename}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, +You can use the following variables: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, %{PendFileRename}, %{PendComputerRename}. =back diff --git a/src/os/windows/wsman/mode/pendingreboot.pm b/src/os/windows/wsman/mode/pendingreboot.pm index b83a16ce5..62e93c81d 100644 --- a/src/os/windows/wsman/mode/pendingreboot.pm +++ b/src/os/windows/wsman/mode/pendingreboot.pm @@ -145,13 +145,13 @@ Print powershell output. =item B<--warning-status> Set warning threshold for status (Default: '%{RebootPending} =~ /true/i'). -Can used special variables like: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, +You can use the following variables: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, %{PendFileRename}, %{PendComputerRename}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, +You can use the following variables: %{RebootPending}, %{WindowsUpdate}, %{CBServicing}, %{CCMClientSDK}, %{PendFileRename}, %{PendComputerRename}. =back diff --git a/src/snmp_standard/mode/interfaces.pm b/src/snmp_standard/mode/interfaces.pm index d6193f0f6..2066fdee1 100644 --- a/src/snmp_standard/mode/interfaces.pm +++ b/src/snmp_standard/mode/interfaces.pm @@ -1585,12 +1585,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/snmp_standard/mode/printererror.pm b/src/snmp_standard/mode/printererror.pm index 6a23f547a..d8731e6c7 100644 --- a/src/snmp_standard/mode/printererror.pm +++ b/src/snmp_standard/mode/printererror.pm @@ -172,22 +172,22 @@ Use that option if your printer provides big-endian bits ordering. =item B<--ok-status> Set warning threshold for status (Default: '%{status} =~ /ok/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /.*/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/snmp_standard/mode/spanningtree.pm b/src/snmp_standard/mode/spanningtree.pm index dc5a623ec..179ccfb5d 100644 --- a/src/snmp_standard/mode/spanningtree.pm +++ b/src/snmp_standard/mode/spanningtree.pm @@ -209,13 +209,13 @@ Filter on port description (can be a regexp). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{op_status}, +You can use the following variables: %{state}, %{op_status}, %{admin_status}, %{port}, %{index}. =item B<--critical-status> Set critical threshold for status (Default: '%{op_status} =~ /up/ && %{state} =~ /blocking|broken/'). -Can used special variables like: %{state}, %{op_status}, +You can use the following variables: %{state}, %{op_status}, %{admin_status}, %{port}, %{index}. =back diff --git a/src/snmp_standard/mode/stringvalue.pm b/src/snmp_standard/mode/stringvalue.pm index 2d635ea33..1cfd0ed3f 100644 --- a/src/snmp_standard/mode/stringvalue.pm +++ b/src/snmp_standard/mode/stringvalue.pm @@ -366,13 +366,14 @@ Allows to use regexp non case-sensitive. =item B<--format-*> -Output format according the threshold. +Output format according to the threshold. Can be: 'ok' (default: '%{filter_rows} value(s)'), 'warning' (default: 'value(s): %{details_warning}'), 'critical' (default: 'value(s): %{details_critical}'), 'unknown' (default: 'value(s): %{details_unknown}'). -Can used: %{rows}, %{filter_rows}, %{details_warning}, %{details_ok}, %{details_critical}, %{details_unknown} +You can use the following variables: +%{rows}, %{filter_rows}, %{details_warning}, %{details_ok}, %{details_critical}, %{details_unknown} =item B<--map-values> @@ -394,7 +395,7 @@ Example to convert octetstring to macaddress: --convert-custom-values='join(":", =item B<--use-perl-mod> -Load additional Perl module (Can be multiple) +Load additional Perl module (can be defined multiple times) Example : --use-perl-mod='Date::Parse' =back diff --git a/src/snmp_standard/mode/vrrp.pm b/src/snmp_standard/mode/vrrp.pm index 067a91e76..45b97e546 100644 --- a/src/snmp_standard/mode/vrrp.pm +++ b/src/snmp_standard/mode/vrrp.pm @@ -144,12 +144,12 @@ Check VRRP status (VRRP-MIB). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{adminState}, %{operStateLast}, %{operState}, %{masterIpAddr} +You can use the following variables: %{adminState}, %{operStateLast}, %{operState}, %{masterIpAddr} =item B<--critical-status> Set critical threshold for status (Default: '%{adminState} eq "up" and %{operState} ne %{operStateLast}'). -Can used special variables like: %{adminState}, %{operStateLast}, %{operState}, %{masterIpAddr} +You can use the following variables: %{adminState}, %{operStateLast}, %{operState}, %{masterIpAddr} =back diff --git a/src/storage/dell/compellent/snmp/mode/globalstatus.pm b/src/storage/dell/compellent/snmp/mode/globalstatus.pm index 4ace0e28d..24907cb37 100644 --- a/src/storage/dell/compellent/snmp/mode/globalstatus.pm +++ b/src/storage/dell/compellent/snmp/mode/globalstatus.pm @@ -131,17 +131,17 @@ Check the overall status of Dell Compellent. =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /nonCritical|other/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /critical|nonRecoverable/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/storage/dell/equallogic/snmp/mode/diskusage.pm b/src/storage/dell/equallogic/snmp/mode/diskusage.pm index c1a8a66dd..656f57c6b 100644 --- a/src/storage/dell/equallogic/snmp/mode/diskusage.pm +++ b/src/storage/dell/equallogic/snmp/mode/diskusage.pm @@ -192,17 +192,17 @@ Filter disk name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{health}, %{status}, %{display} +You can use the following variables: %{health}, %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{health}, %{status}, %{display} +You can use the following variables: %{health}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /on-line|spare|off-line/i'). -Can used special variables like: %{health}, %{status}, %{display} +You can use the following variables: %{health}, %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/dell/me4/restapi/mode/interfaces.pm b/src/storage/dell/me4/restapi/mode/interfaces.pm index da5c4fafe..dc220ff8b 100644 --- a/src/storage/dell/me4/restapi/mode/interfaces.pm +++ b/src/storage/dell/me4/restapi/mode/interfaces.pm @@ -238,17 +238,17 @@ Filter port name (Can be a regexp). =item B<--unknown-port-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{health}, %{display} +You can use the following variables: %{status}, %{health}, %{display} =item B<--warning-port-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{health}, %{display} +You can use the following variables: %{status}, %{health}, %{display} =item B<--critical-port-status> Set critical threshold for status (Default: '%{status} =~ /fault/i'). -Can used special variables like: %{status}, %{health}, %{display} +You can use the following variables: %{status}, %{health}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/dell/powerstore/restapi/mode/alerts.pm b/src/storage/dell/powerstore/restapi/mode/alerts.pm index 03d3d5a79..bde98e134 100644 --- a/src/storage/dell/powerstore/restapi/mode/alerts.pm +++ b/src/storage/dell/powerstore/restapi/mode/alerts.pm @@ -184,12 +184,12 @@ Filter alerts by name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor/i') -Can used special variables like: %{severity}, %{resource}, %{name}, %{timeraised}, %{acknowledged} +You can use the following variables: %{severity}, %{resource}, %{name}, %{timeraised}, %{acknowledged} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /major|critical/i'). -Can used special variables like: %{severity}, %{resource}, %{name}, %{timeraised}, %{acknowledged} +You can use the following variables: %{severity}, %{resource}, %{name}, %{timeraised}, %{acknowledged} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/emc/DataDomain/mode/replication.pm b/src/storage/emc/DataDomain/mode/replication.pm index ba5690004..1721b7397 100644 --- a/src/storage/emc/DataDomain/mode/replication.pm +++ b/src/storage/emc/DataDomain/mode/replication.pm @@ -161,17 +161,17 @@ Example: --filter-counters='^status$' =item B<--unknown-status> Set unknown threshold for status (Default: none). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--warning-status> Set warning threshold for status (Default: '%{state} =~ /initializing|recovering/i'). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /disabledNeedsResync|uninitialized/i'). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/emc/isilon/snmp/mode/clusterusage.pm b/src/storage/emc/isilon/snmp/mode/clusterusage.pm index bd84267ac..877d4ab2b 100644 --- a/src/storage/emc/isilon/snmp/mode/clusterusage.pm +++ b/src/storage/emc/isilon/snmp/mode/clusterusage.pm @@ -224,12 +224,12 @@ Example: --filter-counters='^status$' =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /attn/). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down|invalid/'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> diff --git a/src/storage/emc/unisphere/restapi/mode/pools.pm b/src/storage/emc/unisphere/restapi/mode/pools.pm index fb302d404..74202357b 100644 --- a/src/storage/emc/unisphere/restapi/mode/pools.pm +++ b/src/storage/emc/unisphere/restapi/mode/pools.pm @@ -208,17 +208,17 @@ Filter pool name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /ok_but|degraded|minor/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /major|critical|non_recoverable/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/emc/unisphere/restapi/mode/replications.pm b/src/storage/emc/unisphere/restapi/mode/replications.pm index 08ca8eb79..93ed37dbe 100644 --- a/src/storage/emc/unisphere/restapi/mode/replications.pm +++ b/src/storage/emc/unisphere/restapi/mode/replications.pm @@ -142,32 +142,32 @@ Filter replication name (can be a regexp). =item B<--unknown-health-status> Set unknown threshold for status (Default: '%{health_status} =~ /unknown/i'). -Can used special variables like: %{health_status}, %{display} +You can use the following variables: %{health_status}, %{display} =item B<--warning-health-status> Set warning threshold for status (Default: '%{health_status} =~ /ok_but|degraded|minor/i'). -Can used special variables like: %{health_status}, %{display} +You can use the following variables: %{health_status}, %{display} =item B<--critical-health-status> Set critical threshold for status (Default: '%{health_status} =~ /major|critical|non_recoverable/i'). -Can used special variables like: %{health_status}, %{display} +You can use the following variables: %{health_status}, %{display} =item B<--unknown-repl-status> Set unknown threshold for status (Default: '%{repl_status} =~ /unknown/i'). -Can used special variables like: %{repl_status}, %{display} +You can use the following variables: %{repl_status}, %{display} =item B<--warning-repl-status> Set warning threshold for status (Default: '%{repl_status} =~ /syncing/i'). -Can used special variables like: %{repl_status}, %{display} +You can use the following variables: %{repl_status}, %{display} =item B<--critical-repl-status> Set critical threshold for status (Default: '%{repl_status} =~ /inconsistent/i'). -Can used special variables like: %{repl_status}, %{display} +You can use the following variables: %{repl_status}, %{display} =back diff --git a/src/storage/emc/unisphere/restapi/mode/storageresources.pm b/src/storage/emc/unisphere/restapi/mode/storageresources.pm index f7570be36..41325df5e 100644 --- a/src/storage/emc/unisphere/restapi/mode/storageresources.pm +++ b/src/storage/emc/unisphere/restapi/mode/storageresources.pm @@ -211,17 +211,17 @@ Filter name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /ok_but|degraded|minor/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /major|critical|non_recoverable/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/emc/vplex/restapi/mode/clustercommunication.pm b/src/storage/emc/vplex/restapi/mode/clustercommunication.pm index 9b7b7af84..e24d1616d 100644 --- a/src/storage/emc/vplex/restapi/mode/clustercommunication.pm +++ b/src/storage/emc/vplex/restapi/mode/clustercommunication.pm @@ -103,12 +103,12 @@ Filter components by name (can be a regexp). =item B<--warning-operational-status> Set warning threshold for status. -Can used special variables like: %{operational_state}, %{admin_state}, %{name} +You can use the following variables: %{operational_state}, %{admin_state}, %{name} =item B<--critical-operational-status> Set critical threshold for status (Default: '%{admin_state} eq "enabled" and %{operational_state} !~ /cluster-in-contact|in-contact/i'). -Can used special variables like: %{operational_state}, %{admin_state}, %{name} +You can use the following variables: %{operational_state}, %{admin_state}, %{name} =back diff --git a/src/storage/emc/vplex/restapi/mode/clusterdevices.pm b/src/storage/emc/vplex/restapi/mode/clusterdevices.pm index a1ccc69c2..9f26d441d 100644 --- a/src/storage/emc/vplex/restapi/mode/clusterdevices.pm +++ b/src/storage/emc/vplex/restapi/mode/clusterdevices.pm @@ -114,12 +114,12 @@ Filter devices by device name (can be a regexp). =item B<--warning-health-status> Set warning threshold for status. -Can used special variables like: %{health_state}, %{cluster_name}, %{device_name} +You can use the following variables: %{health_state}, %{cluster_name}, %{device_name} =item B<--critical-health-status> Set critical threshold for status (Default: '%{health_state} ne "ok"'). -Can used special variables like: %{health_state}, %{cluster_name}, %{device_name} +You can use the following variables: %{health_state}, %{cluster_name}, %{device_name} =back diff --git a/src/storage/emc/vplex/restapi/mode/directors.pm b/src/storage/emc/vplex/restapi/mode/directors.pm index 46755432e..d5ec9e9b8 100644 --- a/src/storage/emc/vplex/restapi/mode/directors.pm +++ b/src/storage/emc/vplex/restapi/mode/directors.pm @@ -137,52 +137,52 @@ Filter directors by director name (can be a regexp). =item B<--warning-health-status> Set warning threshold for status. -Can used special variables like: %{operational_status}, %{engine_id}, %{director_name} +You can use the following variables: %{operational_status}, %{engine_id}, %{director_name} =item B<--critical-health-status> Set critical threshold for status (Default: '%{health_state} ne "ok"'). -Can used special variables like: %{operational_status}, %{engine_id}, %{director_name} +You can use the following variables: %{operational_status}, %{engine_id}, %{director_name} =item B<--warning-communication-status> Set warning threshold for status. -Can used special variables like: %{communication_status}, %{engine_id}, %{director_name} +You can use the following variables: %{communication_status}, %{engine_id}, %{director_name} =item B<--critical-communication-status> Set critical threshold for status (Default: '%{communication_status} ne "ok"'). -Can used special variables like: %{communication_status}, %{engine_id}, %{director_name} +You can use the following variables: %{communication_status}, %{engine_id}, %{director_name} =item B<--warning-temperature-status> Set warning threshold for status. -Can used special variables like: %{temperature_threshold_exceeded}, %{engine_id}, %{director_name} +You can use the following variables: %{temperature_threshold_exceeded}, %{engine_id}, %{director_name} =item B<--critical-temperature-status> Set critical threshold for status (Default: '%{temperature_threshold_exceeded} ne "false"'). -Can used special variables like: %{temperature_threshold_exceeded}, %{engine_id}, %{director_name} +You can use the following variables: %{temperature_threshold_exceeded}, %{engine_id}, %{director_name} =item B<--warning-voltage-status> Set warning threshold for status. -Can used special variables like: %{voltage_threshold_exceeded}, %{engine_id}, %{director_name} +You can use the following variables: %{voltage_threshold_exceeded}, %{engine_id}, %{director_name} =item B<--critical-voltage-status> Set critical threshold for status (Default: '%{voltage_threshold_exceeded} ne "false"'). -Can used special variables like: %{voltage_threshold_exceeded}, %{engine_id}, %{director_name} +You can use the following variables: %{voltage_threshold_exceeded}, %{engine_id}, %{director_name} =item B<--warning-vplex-kdriver-status> Set warning threshold for status. -Can used special variables like: %{vplex_kdriver_status}, %{engine_id}, %{director_name} +You can use the following variables: %{vplex_kdriver_status}, %{engine_id}, %{director_name} =item B<--critical-vplex-kdriver-status> Set critical threshold for status (Default: '%{vplex_kdriver_status} ne "ok"'). -Can used special variables like: %{vplex_kdriver_status}, %{engine_id}, %{director_name} +You can use the following variables: %{vplex_kdriver_status}, %{engine_id}, %{director_name} =back diff --git a/src/storage/emc/vplex/restapi/mode/distributeddevices.pm b/src/storage/emc/vplex/restapi/mode/distributeddevices.pm index 1501095df..8649da724 100644 --- a/src/storage/emc/vplex/restapi/mode/distributeddevices.pm +++ b/src/storage/emc/vplex/restapi/mode/distributeddevices.pm @@ -111,32 +111,32 @@ Filter devices by device name (can be a regexp). =item B<--warning-operational-status> Set warning threshold for status. -Can used special variables like: %{operational_status}, %{device_name} +You can use the following variables: %{operational_status}, %{device_name} =item B<--critical-operational-status> Set critical threshold for status (Default: '%{operational_status} ne "ok"'). -Can used special variables like: %{operational_status}, %{device_name} +You can use the following variables: %{operational_status}, %{device_name} =item B<--warning-health-status> Set warning threshold for status. -Can used special variables like: %{health_state}, %{device_name} +You can use the following variables: %{health_state}, %{device_name} =item B<--critical-health-status> Set critical threshold for status (Default: '%{health_state} ne "ok"'). -Can used special variables like: %{health_state}, %{device_name} +You can use the following variables: %{health_state}, %{device_name} =item B<--warning-service-status> Set warning threshold for status. -Can used special variables like: %{service_status}, %{device_name} +You can use the following variables: %{service_status}, %{device_name} =item B<--critical-service-status> Set critical threshold for status (Default: '%{service_status} ne "running"'). -Can used special variables like: %{service_status}, %{device_name} +You can use the following variables: %{service_status}, %{device_name} =back diff --git a/src/storage/emc/vplex/restapi/mode/fans.pm b/src/storage/emc/vplex/restapi/mode/fans.pm index f433cbaa5..fa464a343 100644 --- a/src/storage/emc/vplex/restapi/mode/fans.pm +++ b/src/storage/emc/vplex/restapi/mode/fans.pm @@ -112,22 +112,22 @@ Filter fans by fan name (can be a regexp). =item B<--warning-operational-status> Set warning threshold for status. -Can used special variables like: %{operational_status}, %{engine_id}, %{fan_name} +You can use the following variables: %{operational_status}, %{engine_id}, %{fan_name} =item B<--critical-operational-status> Set critical threshold for status (Default: '%{operational_status} ne "online"'). -Can used special variables like: %{operational_status}, %{engine_id}, %{fan_name} +You can use the following variables: %{operational_status}, %{engine_id}, %{fan_name} =item B<--warning-speed-status> Set warning threshold for status. -Can used special variables like: %{speed_threshold_exceeded}, %{engine_id}, %{fan_name} +You can use the following variables: %{speed_threshold_exceeded}, %{engine_id}, %{fan_name} =item B<--critical-speed-status> Set critical threshold for status (Default: '%{operational_status} ne "online"'). -Can used special variables like: %{speed_threshold_exceeded}, %{engine_id}, %{fan_name} +You can use the following variables: %{speed_threshold_exceeded}, %{engine_id}, %{fan_name} =back diff --git a/src/storage/emc/vplex/restapi/mode/psus.pm b/src/storage/emc/vplex/restapi/mode/psus.pm index 1b8432ff8..cde4c3a04 100644 --- a/src/storage/emc/vplex/restapi/mode/psus.pm +++ b/src/storage/emc/vplex/restapi/mode/psus.pm @@ -111,22 +111,22 @@ Filter power supplies by power supply name (can be a regexp). =item B<--warning-operational-status> Set warning threshold for status. -Can used special variables like: %{operational_status}, %{engine_id}, %{psu_name} +You can use the following variables: %{operational_status}, %{engine_id}, %{psu_name} =item B<--critical-operational-status> Set critical threshold for status (Default: '%{operational_status} ne "online"'). -Can used special variables like: %{operational_status}, %{engine_id}, %{psu_name} +You can use the following variables: %{operational_status}, %{engine_id}, %{psu_name} =item B<--warning-temperature-status> Set warning threshold for status. -Can used special variables like: %{temperature_threshold_exceeded}, %{engine_id}, %{psu_name} +You can use the following variables: %{temperature_threshold_exceeded}, %{engine_id}, %{psu_name} =item B<--critical-temperature-status> Set critical threshold for status (Default: '%{operational_status} ne "online"'). -Can used special variables like: %{temperature_threshold_exceeded}, %{engine_id}, %{psu_name} +You can use the following variables: %{temperature_threshold_exceeded}, %{engine_id}, %{psu_name} =back diff --git a/src/storage/emc/vplex/restapi/mode/storagevolumes.pm b/src/storage/emc/vplex/restapi/mode/storagevolumes.pm index a8dd6f838..8e205697e 100644 --- a/src/storage/emc/vplex/restapi/mode/storagevolumes.pm +++ b/src/storage/emc/vplex/restapi/mode/storagevolumes.pm @@ -114,12 +114,12 @@ Filter volumes by volume name (can be a regexp). =item B<--warning-health-status> Set warning threshold for status. -Can used special variables like: %{health_state}, %{cluster_name}, %{volume_name} +You can use the following variables: %{health_state}, %{cluster_name}, %{volume_name} =item B<--critical-health-status> Set critical threshold for status (Default: '%{health_state} ne "ok"'). -Can used special variables like: %{health_state}, %{cluster_name}, %{volume_name} +You can use the following variables: %{health_state}, %{cluster_name}, %{volume_name} =back diff --git a/src/storage/emc/xtremio/restapi/custom/xtremioapi.pm b/src/storage/emc/xtremio/restapi/custom/xtremioapi.pm index 7cd75502f..88c6afedc 100644 --- a/src/storage/emc/xtremio/restapi/custom/xtremioapi.pm +++ b/src/storage/emc/xtremio/restapi/custom/xtremioapi.pm @@ -195,7 +195,7 @@ sub get_details_lookup_clusters { } # object is not found. - $self->{output}->add_option_msg(short_msg => "xtremio api issue: cannot found object details"); + $self->{output}->add_option_msg(short_msg => "xtremio api issue: cannot find object details"); $self->{output}->option_exit(); } diff --git a/src/storage/emc/xtremio/restapi/mode/dpg.pm b/src/storage/emc/xtremio/restapi/mode/dpg.pm index ffb38718b..18909eab7 100644 --- a/src/storage/emc/xtremio/restapi/mode/dpg.pm +++ b/src/storage/emc/xtremio/restapi/mode/dpg.pm @@ -146,17 +146,17 @@ Filter data protection groups by name (can be a regexp). =item B<--unknown-health-indicator> Set unknown threshold for status. -Can used special variables like: %{health}, %{indicator} +You can use the following variables: %{health}, %{indicator} =item B<--warning-health-indicator> Set warning threshold for status. -Can used special variables like: %{health}, %{indicator} +You can use the following variables: %{health}, %{indicator} =item B<--critical-health-indicator> Set critical threshold for status (Default: '%{health} !~ /done|normal|null/i'). -Can used special variables like: %{health}, %{indicator} +You can use the following variables: %{health}, %{indicator} =back diff --git a/src/storage/emc/xtremio/restapi/mode/storagecontrollers.pm b/src/storage/emc/xtremio/restapi/mode/storagecontrollers.pm index 907ad7148..250e94f3f 100644 --- a/src/storage/emc/xtremio/restapi/mode/storagecontrollers.pm +++ b/src/storage/emc/xtremio/restapi/mode/storagecontrollers.pm @@ -149,17 +149,17 @@ Filter storage controllers by name (can be a regexp). =item B<--unknown-health-indicator> Set unknown threshold for status. -Can used special variables like: %{health}, %{indicator} +You can use the following variables: %{health}, %{indicator} =item B<--warning-health-indicator> Set warning threshold for status. -Can used special variables like: %{health}, %{indicator} +You can use the following variables: %{health}, %{indicator} =item B<--critical-health-indicator> Set critical threshold for status (Default: '%{health} !~ /done|normal|null/i'). -Can used special variables like: %{health}, %{indicator} +You can use the following variables: %{health}, %{indicator} =back diff --git a/src/storage/exagrid/snmp/mode/serverusage.pm b/src/storage/exagrid/snmp/mode/serverusage.pm index 3107b410f..9b7324d1b 100644 --- a/src/storage/exagrid/snmp/mode/serverusage.pm +++ b/src/storage/exagrid/snmp/mode/serverusage.pm @@ -190,12 +190,12 @@ Example: --filter-counters='^status$' =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /error/i'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hitachi/hcp/snmp/mode/nodes.pm b/src/storage/hitachi/hcp/snmp/mode/nodes.pm index bf2a51f9e..2fe512320 100644 --- a/src/storage/hitachi/hcp/snmp/mode/nodes.pm +++ b/src/storage/hitachi/hcp/snmp/mode/nodes.pm @@ -412,62 +412,62 @@ Filter nodes by id (can be a regexp). =item B<--unknown-node-status> Set unknown threshold for status. -Can used special variables like: %{node_status}, %{node_id} +You can use the following variables: %{node_status}, %{node_id} =item B<--warning-node-status> Set warning threshold for status. -Can used special variables like: %{node_status}, %{node_id} +You can use the following variables: %{node_status}, %{node_id} =item B<--critical-node-status> Set critical threshold for status (Default: '%{node_status} eq "unavailable"'). -Can used special variables like: %{node_status}, %{node_id} +You can use the following variables: %{node_status}, %{node_id} =item B<--unknown-nic-status> Set unknown threshold for status. -Can used special variables like: %{nic_status}, %{node_id} +You can use the following variables: %{nic_status}, %{node_id} =item B<--warning-nic-status> Set warning threshold for status. -Can used special variables like: %{nic_status}, %{node_id} +You can use the following variables: %{nic_status}, %{node_id} =item B<--critical-nic-status> Set critical threshold for status (Default: '%{nic_status} eq "failed"'). -Can used special variables like: %{nic_status}, %{node_id} +You can use the following variables: %{nic_status}, %{node_id} =item B<--unknown-san-path-status> Set unknown threshold for status. -Can used special variables like: %{san_path_status}, %{node_id} +You can use the following variables: %{san_path_status}, %{node_id} =item B<--warning-san-path-status> Set warning threshold for status. -Can used special variables like: %{san_path_status}, %{node_id} +You can use the following variables: %{san_path_status}, %{node_id} =item B<--critical-san-path-status> Set critical threshold for status (Default: '%{san_path_status} eq "error"'). -Can used special variables like: %{san_path_status}, %{node_id} +You can use the following variables: %{san_path_status}, %{node_id} =item B<--unknown-bbu-status> Set unknown threshold for status. -Can used special variables like: %{bbu_status}, %{node_id} +You can use the following variables: %{bbu_status}, %{node_id} =item B<--warning-bbu-status> Set warning threshold for status. -Can used special variables like: %{bbu_status}, %{node_id} +You can use the following variables: %{bbu_status}, %{node_id} =item B<--critical-bbu-status> Set critical threshold for status (Default: '%{bbu_status} !~ /healthy/i'). -Can used special variables like: %{bbu_status}, %{node_id} +You can use the following variables: %{bbu_status}, %{node_id} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hitachi/hcp/snmp/mode/volumes.pm b/src/storage/hitachi/hcp/snmp/mode/volumes.pm index e4e412d37..0a97dfaea 100644 --- a/src/storage/hitachi/hcp/snmp/mode/volumes.pm +++ b/src/storage/hitachi/hcp/snmp/mode/volumes.pm @@ -232,17 +232,17 @@ Filter volumes by node id (can be a regexp). =item B<--unknown-volume-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{node_id}, %{label} +You can use the following variables: %{status}, %{node_id}, %{label} =item B<--warning-volume-status> Set warning threshold for status (Default: '%{status} =~ /degraded/'). -Can used special variables like: %{status}, %{node_id}, %{label} +You can use the following variables: %{status}, %{node_id}, %{label} =item B<--critical-volume-status> Set critical threshold for status (Default: '%{status} =~ /broken/'). -Can used special variables like: %{status}, %{node_id}, %{label} +You can use the following variables: %{status}, %{node_id}, %{label} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/3par/ssh/mode/afc.pm b/src/storage/hp/3par/ssh/mode/afc.pm index 5ae403c85..b2e904eb4 100644 --- a/src/storage/hp/3par/ssh/mode/afc.pm +++ b/src/storage/hp/3par/ssh/mode/afc.pm @@ -281,7 +281,7 @@ Filter volumes by name (can be a regexp). Set thresholds for status (Default critical: '%{status} !~ /normal/i') -Can used special variables like: %{status}, %{node_id} +You can use the following variables: %{status}, %{node_id} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/3par/ssh/mode/cages.pm b/src/storage/hp/3par/ssh/mode/cages.pm index 1b9820b7d..1de203892 100644 --- a/src/storage/hp/3par/ssh/mode/cages.pm +++ b/src/storage/hp/3par/ssh/mode/cages.pm @@ -324,7 +324,7 @@ Filter cages by id (can be a regexp). Set thresholds for status (Default critical: '%{status} !~ /Normal/i') -Can used special variables like: %{status}, %{cage_id} +You can use the following variables: %{status}, %{cage_id} =item B<--unknown-board-firmware-status> @@ -336,7 +336,7 @@ Can used special variables like: %{status}, %{cage_id} Set thresholds for status (Default critical: '%{status} !~ /Current/i') -Can used special variables like: %{status}, %{cage_id}, %{board_id} +You can use the following variables: %{status}, %{cage_id}, %{board_id} =item B<--unknown-board-[self|partner]-status> @@ -348,7 +348,7 @@ Can used special variables like: %{status}, %{cage_id}, %{board_id} Set thresholds for status (Default critical: '%{status} !~ /ok/i') -Can used special variables like: %{status}, %{cage_id}, %{board_id} +You can use the following variables: %{status}, %{cage_id}, %{board_id} =item B<--unknown-psu-status> @@ -360,7 +360,7 @@ Can used special variables like: %{status}, %{cage_id}, %{board_id} Set thresholds for status (Default critical: '%{status} !~ /ok/i') -Can used special variables like: %{status}, %{cage_id}, %{psu_id} +You can use the following variables: %{status}, %{cage_id}, %{psu_id} =item B<--unknown-psu-[ac|dc|fan]-status> @@ -372,7 +372,7 @@ Can used special variables like: %{status}, %{cage_id}, %{psu_id} Set thresholds for status (Default critical: '%{status} !~ /ok/i') -Can used special variables like: %{status}, %{cage_id}, %{psu_id} +You can use the following variables: %{status}, %{cage_id}, %{psu_id} =item B<--unknown-drive-status> @@ -384,7 +384,7 @@ Can used special variables like: %{status}, %{cage_id}, %{psu_id} Set thresholds for status (Default critical: '%{status} !~ /normal/i') -Can used special variables like: %{status}, %{cage_id}, %{drive_id} +You can use the following variables: %{status}, %{cage_id}, %{drive_id} =item B<--unknown-drive-[porta|portb]-status> @@ -396,7 +396,7 @@ Can used special variables like: %{status}, %{cage_id}, %{drive_id} Set thresholds for status (Default critical: '%{status} !~ /ok/i') -Can used special variables like: %{status}, %{cage_id}, %{drive_id} +You can use the following variables: %{status}, %{cage_id}, %{drive_id} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/3par/ssh/mode/diskusage.pm b/src/storage/hp/3par/ssh/mode/diskusage.pm index a29cf8759..ba8f8e1d9 100644 --- a/src/storage/hp/3par/ssh/mode/diskusage.pm +++ b/src/storage/hp/3par/ssh/mode/diskusage.pm @@ -167,12 +167,12 @@ Filter disk name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /normal/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/3par/ssh/mode/nodes.pm b/src/storage/hp/3par/ssh/mode/nodes.pm index a6361c587..1031cc427 100644 --- a/src/storage/hp/3par/ssh/mode/nodes.pm +++ b/src/storage/hp/3par/ssh/mode/nodes.pm @@ -192,17 +192,17 @@ Filter nodes by id (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{node_id} +You can use the following variables: %{status}, %{node_id} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{node_id} +You can use the following variables: %{status}, %{node_id} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{node_id} +You can use the following variables: %{status}, %{node_id} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/3par/ssh/mode/psu.pm b/src/storage/hp/3par/ssh/mode/psu.pm index f2d024174..978efb2d4 100644 --- a/src/storage/hp/3par/ssh/mode/psu.pm +++ b/src/storage/hp/3par/ssh/mode/psu.pm @@ -240,77 +240,77 @@ Filter power supplies by id (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--unknown-ac-status> Set unknown threshold for AC status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--warning-ac-status> Set warning threshold for AC status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--critical-ac-status> Set critical threshold for AC status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--unknown-dc-status> Set unknown threshold for DC status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--warning-dc-status> Set warning threshold for DC status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--critical-dc-status> Set critical threshold for DC status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--unknown-fan-status> Set unknown threshold for fan status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--warning-fan-status> Set warning threshold for fan status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--critical-fan-status> Set critical threshold for fan status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--unknown-battery-status> Set unknown threshold for battery status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--warning-battery-status> Set warning threshold for battery status. -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--critical-battery-status> Set critical threshold for battery status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{node_id}, %{psu_id} +You can use the following variables: %{status}, %{node_id}, %{psu_id} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/lefthand/snmp/mode/volumeusage.pm b/src/storage/hp/lefthand/snmp/mode/volumeusage.pm index ffb50ca7a..302eb1c0f 100644 --- a/src/storage/hp/lefthand/snmp/mode/volumeusage.pm +++ b/src/storage/hp/lefthand/snmp/mode/volumeusage.pm @@ -302,12 +302,12 @@ Filter volume name (can be a regexp). =item B<--warning-replication-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-replication-status> Set critical threshold for status (Default: '%{status} !~ /normal/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> diff --git a/src/storage/hp/p2000/xmlapi/mode/controllers.pm b/src/storage/hp/p2000/xmlapi/mode/controllers.pm index c74fba14d..51ea2754e 100644 --- a/src/storage/hp/p2000/xmlapi/mode/controllers.pm +++ b/src/storage/hp/p2000/xmlapi/mode/controllers.pm @@ -392,77 +392,77 @@ Filter controllers by controller name (can be a regexp). =item B<--unknown-controller-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-controller-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-controller-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-network-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-network-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-network-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-port-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-port-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-port-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-expander-port-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-expander-port-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-expander-port-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-compact-flash-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-compact-flash-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-compact-flash-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/p2000/xmlapi/mode/vdisks.pm b/src/storage/hp/p2000/xmlapi/mode/vdisks.pm index dc82c23d9..8db795db3 100644 --- a/src/storage/hp/p2000/xmlapi/mode/vdisks.pm +++ b/src/storage/hp/p2000/xmlapi/mode/vdisks.pm @@ -194,17 +194,17 @@ Filter virtual disk name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/storeonce/3/restapi/mode/clusterusage.pm b/src/storage/hp/storeonce/3/restapi/mode/clusterusage.pm index 89375f848..d68f4ada6 100644 --- a/src/storage/hp/storeonce/3/restapi/mode/clusterusage.pm +++ b/src/storage/hp/storeonce/3/restapi/mode/clusterusage.pm @@ -227,12 +227,12 @@ Filter cluster name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{health} =~ /warning/'). -Can used special variables like: %{health}, %{display} +You can use the following variables: %{health}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{health} =~ /critical/'). -Can used special variables like: %{health}, %{display} +You can use the following variables: %{health}, %{display} =item B<--warning-*> diff --git a/src/storage/hp/storeonce/3/restapi/mode/fcsusage.pm b/src/storage/hp/storeonce/3/restapi/mode/fcsusage.pm index 9526f1366..819e7b978 100644 --- a/src/storage/hp/storeonce/3/restapi/mode/fcsusage.pm +++ b/src/storage/hp/storeonce/3/restapi/mode/fcsusage.pm @@ -158,12 +158,12 @@ Filter name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{is_online} == 1 and %{health} =~ /warning/i'). -Can used special variables like: %{health}, %{is_online}, %{display} +You can use the following variables: %{health}, %{is_online}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{is_online} == 1 and %{health} =~ /critical/i'). -Can used special variables like: %{health}, %{is_online}, %{display} +You can use the following variables: %{health}, %{is_online}, %{display} =item B<--warning-*> diff --git a/src/storage/hp/storeonce/3/restapi/mode/nasusage.pm b/src/storage/hp/storeonce/3/restapi/mode/nasusage.pm index e76ba26ca..a9ff7fa08 100644 --- a/src/storage/hp/storeonce/3/restapi/mode/nasusage.pm +++ b/src/storage/hp/storeonce/3/restapi/mode/nasusage.pm @@ -171,22 +171,22 @@ Filter nas name (can be a regexp). =item B<--warning-nas-status> Set warning threshold for status (Default: '%{health} =~ /warning/i'). -Can used special variables like: %{health}, %{replication_health}, %{display} +You can use the following variables: %{health}, %{replication_health}, %{display} =item B<--critical-nas-status> Set critical threshold for status (Default: '%{health} =~ /critical/i'). -Can used special variables like: %{health}, %{replication_health}, %{display} +You can use the following variables: %{health}, %{replication_health}, %{display} =item B<--warning-share-status> Set warning threshold for status (Default: '%{health} =~ /warning/i'). -Can used special variables like: %{health}, %{replication_health}, %{display} +You can use the following variables: %{health}, %{replication_health}, %{display} =item B<--critical-share-status> Set critical threshold for status (Default: '%{health} =~ /critical/i'). -Can used special variables like: %{health}, %{replication_health}, %{display} +You can use the following variables: %{health}, %{replication_health}, %{display} =back diff --git a/src/storage/hp/storeonce/3/restapi/mode/servicesetusage.pm b/src/storage/hp/storeonce/3/restapi/mode/servicesetusage.pm index 6736d1ae4..2f72470ab 100644 --- a/src/storage/hp/storeonce/3/restapi/mode/servicesetusage.pm +++ b/src/storage/hp/storeonce/3/restapi/mode/servicesetusage.pm @@ -225,12 +225,12 @@ Filter service set name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{health} =~ /warning/). -Can used special variables like: %{health}, %{replication_health}, %{housekeeping_health}, %{display} +You can use the following variables: %{health}, %{replication_health}, %{housekeeping_health}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{health} =~ /critical/'). -Can used special variables like: %{health}, %{replication_health}, %{housekeeping_health}, %{display} +You can use the following variables: %{health}, %{replication_health}, %{housekeeping_health}, %{display} =item B<--warning-*> diff --git a/src/storage/hp/storeonce/4/restapi/mode/appliances.pm b/src/storage/hp/storeonce/4/restapi/mode/appliances.pm index 5cd815462..70c799ff8 100644 --- a/src/storage/hp/storeonce/4/restapi/mode/appliances.pm +++ b/src/storage/hp/storeonce/4/restapi/mode/appliances.pm @@ -232,17 +232,17 @@ Filter appliances by hostname. =item B<--unknown-service-status> Set unknown threshold for status. -Can used special variables like: %{service}, %{status} +You can use the following variables: %{service}, %{status} =item B<--warning-service-status> Set warning threshold for status (Default: '%{status} =~ /warning/i'). -Can used special variables like: %{service}, %{status} +You can use the following variables: %{service}, %{status} =item B<--critical-service-status> Set critical threshold for status (Default: '%{status} =~ /critical/i'). -Can used special variables like: %{service}, %{status} +You can use the following variables: %{service}, %{status} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/hp/storeonce/4/restapi/mode/stores.pm b/src/storage/hp/storeonce/4/restapi/mode/stores.pm index b7ae5cb60..c1a3cd2e0 100644 --- a/src/storage/hp/storeonce/4/restapi/mode/stores.pm +++ b/src/storage/hp/storeonce/4/restapi/mode/stores.pm @@ -202,17 +202,17 @@ Filter stores by hostname. =item B<--unknown-health> Set unknown threshold for status (Default: '%{health} =~ /unknown/i'). -Can used special variables like: %{health}, %{name} +You can use the following variables: %{health}, %{name} =item B<--warning-health> Set warning threshold for status (Default: '%{health} =~ /warning/i'). -Can used special variables like: %{health}, %{name} +You can use the following variables: %{health}, %{name} =item B<--critical-health> Set critical threshold for status (Default: '%{health} =~ /critical/i'). -Can used special variables like: %{health}, %{name} +You can use the following variables: %{health}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/huawei/oceanstor/snmp/mode/controllers.pm b/src/storage/huawei/oceanstor/snmp/mode/controllers.pm index 2c8fa2771..a3ea04983 100644 --- a/src/storage/huawei/oceanstor/snmp/mode/controllers.pm +++ b/src/storage/huawei/oceanstor/snmp/mode/controllers.pm @@ -191,17 +191,17 @@ Filter controller by ID (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{health_status}, %{running_status}, %{id} +You can use the following variables: %{health_status}, %{running_status}, %{id} =item B<--warning-status> Set warning threshold for status (Default: '%{health_status} =~ /degraded|partially broken/i'). -Can used special variables like: %{health_status}, %{running_status}, %{id} +You can use the following variables: %{health_status}, %{running_status}, %{id} =item B<--critical-status> Set critical threshold for status (Default: '%{health_status} =~ /fault|fail/i'). -Can used special variables like: %{health_status}, %{running_status}, %{id} +You can use the following variables: %{health_status}, %{running_status}, %{id} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/huawei/oceanstor/snmp/mode/storagepools.pm b/src/storage/huawei/oceanstor/snmp/mode/storagepools.pm index f359406d0..7f703d4bd 100644 --- a/src/storage/huawei/oceanstor/snmp/mode/storagepools.pm +++ b/src/storage/huawei/oceanstor/snmp/mode/storagepools.pm @@ -237,17 +237,17 @@ Filter storage pool by domain name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{health_status}, %{running_status}, %{name} +You can use the following variables: %{health_status}, %{running_status}, %{name} =item B<--warning-status> Set warning threshold for status (Default: '%{health_status} =~ /degraded|partially broken/i'). -Can used special variables like: %{health_status}, %{running_status}, %{name} +You can use the following variables: %{health_status}, %{running_status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{health_status} =~ /fault|fail/i'). -Can used special variables like: %{health_status}, %{running_status}, %{name} +You can use the following variables: %{health_status}, %{running_status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/ibm/storwize/ssh/mode/poolusage.pm b/src/storage/ibm/storwize/ssh/mode/poolusage.pm index 1ab0ed43a..36d7b4587 100644 --- a/src/storage/ibm/storwize/ssh/mode/poolusage.pm +++ b/src/storage/ibm/storwize/ssh/mode/poolusage.pm @@ -202,12 +202,12 @@ Filter pool name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /offline/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/lenovo/iomega/snmp/mode/interfaces.pm b/src/storage/lenovo/iomega/snmp/mode/interfaces.pm index 244e515d3..7249cbe21 100644 --- a/src/storage/lenovo/iomega/snmp/mode/interfaces.pm +++ b/src/storage/lenovo/iomega/snmp/mode/interfaces.pm @@ -95,12 +95,12 @@ If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/oncommandapi/mode/aggregateraidstatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/aggregateraidstatus.pm index 145126b4a..446c43d2d 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/aggregateraidstatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/aggregateraidstatus.pm @@ -160,12 +160,12 @@ Can be: 'name', 'node', 'cluster' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{type}, %{size} +You can use the following variables: %{status}, %{type}, %{size} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /normal/i'). -Can used special variables like: %{status}, %{type}, %{size} +You can use the following variables: %{status}, %{type}, %{size} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/aggregatestatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/aggregatestatus.pm index 93db0ede3..8f48347eb 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/aggregatestatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/aggregatestatus.pm @@ -158,12 +158,12 @@ Can be: 'name', 'node', 'cluster' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{mirror_status} +You can use the following variables: %{state}, %{mirror_status} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /online/i'). -Can used special variables like: %{state}, %{mirror_status} +You can use the following variables: %{state}, %{mirror_status} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/clusterstatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/clusterstatus.pm index a1e1a697f..7994adc43 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/clusterstatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/clusterstatus.pm @@ -136,12 +136,12 @@ Filter snapmirror name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{metro_cluster_mode}, %{metro_cluster_configuration_state} +You can use the following variables: %{status}, %{metro_cluster_mode}, %{metro_cluster_configuration_state} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /ok/i'). -Can used special variables like: %{status}, %{metro_cluster_mode}, %{metro_cluster_configuration_state} +You can use the following variables: %{status}, %{metro_cluster_mode}, %{metro_cluster_configuration_state} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/fcportstatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/fcportstatus.pm index 6500ec11a..0f46283d2 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/fcportstatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/fcportstatus.pm @@ -141,12 +141,12 @@ Can be: 'name', 'volume' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{state} +You can use the following variables: %{state}, %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /online/i || %{state} !~ /online/i'). -Can used special variables like: %{status}, %{state} +You can use the following variables: %{status}, %{state} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/nodefailoverstatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/nodefailoverstatus.pm index 56a3d1445..a94f3ff1a 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/nodefailoverstatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/nodefailoverstatus.pm @@ -154,12 +154,12 @@ Can be: 'name', 'clusters' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{interconnect}, %{current_mode}, %{take_over_possible} +You can use the following variables: %{state}, %{interconnect}, %{current_mode}, %{take_over_possible} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /connected/i || %{interconnect} !~ /up/i'). -Can used special variables like: %{state}, %{interconnect}, %{current_mode}, %{take_over_possible} +You can use the following variables: %{state}, %{interconnect}, %{current_mode}, %{take_over_possible} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/nodehardwarestatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/nodehardwarestatus.pm index d986aabdb..b7ab839b8 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/nodehardwarestatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/nodehardwarestatus.pm @@ -182,13 +182,13 @@ Can be: 'failed-fans', 'psu'. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{temperature}, %{battery_status} +You can use the following variables: %{status}, %{temperature}, %{battery_status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /not healthy/i || %{temperature} !~ /ok/i || %{battery_status} !~ /battery_ok|battery_fully_charge|battery_over_charged/i'). -Can used special variables like: %{status}, %{temperature}, %{battery_status} +You can use the following variables: %{status}, %{temperature}, %{battery_status} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/qtreestatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/qtreestatus.pm index 67a978668..304390fdc 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/qtreestatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/qtreestatus.pm @@ -146,12 +146,12 @@ Can be: 'name', 'volume' (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state} +You can use the following variables: %{state} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status} +You can use the following variables: %{status} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/snapmirrorstatus.pm b/src/storage/netapp/ontap/oncommandapi/mode/snapmirrorstatus.pm index c9abd8e97..356fb695f 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/snapmirrorstatus.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/snapmirrorstatus.pm @@ -131,12 +131,12 @@ Filter snapmirror name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{update} +You can use the following variables: %{state}, %{update} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /snapmirrored/i || %{update} =~ /not healthy/i'). -Can used special variables like: %{state}, %{update} +You can use the following variables: %{state}, %{update} =back diff --git a/src/storage/netapp/ontap/oncommandapi/mode/volumes.pm b/src/storage/netapp/ontap/oncommandapi/mode/volumes.pm index cca82652b..c281e43a3 100644 --- a/src/storage/netapp/ontap/oncommandapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/oncommandapi/mode/volumes.pm @@ -433,17 +433,17 @@ Filter volumes by storage virtual machine name. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{volumeName}, %{svmName} +You can use the following variables: %{state}, %{volumeName}, %{svmName} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{volumeName}, %{svmName} +You can use the following variables: %{state}, %{volumeName}, %{svmName} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /online/i'). -Can used special variables like: %{state}, %{volumeName}, %{svmName} +You can use the following variables: %{state}, %{volumeName}, %{svmName} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/restapi/mode/aggregates.pm b/src/storage/netapp/ontap/restapi/mode/aggregates.pm index 2884de6a8..f210897e4 100644 --- a/src/storage/netapp/ontap/restapi/mode/aggregates.pm +++ b/src/storage/netapp/ontap/restapi/mode/aggregates.pm @@ -283,17 +283,17 @@ Filter aggregates by aggregate name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /online/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/restapi/mode/cluster.pm b/src/storage/netapp/ontap/restapi/mode/cluster.pm index 3f6b7a4c2..e246cc8ed 100644 --- a/src/storage/netapp/ontap/restapi/mode/cluster.pm +++ b/src/storage/netapp/ontap/restapi/mode/cluster.pm @@ -250,17 +250,17 @@ Example: --filter-counters='node-status' =item B<--unknown-node-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{link_status}, %{display} +You can use the following variables: %{state}, %{link_status}, %{display} =item B<--warning-node-status> Set warning threshold for status. -Can used special variables like: %{state}, %{link_status}, %{display} +You can use the following variables: %{state}, %{link_status}, %{display} =item B<--critical-node-status> Set critical threshold for status (Default: '%{state} ne "online"'). -Can used special variables like: %{state}, %{link_status}, %{display} +You can use the following variables: %{state}, %{link_status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/restapi/mode/luns.pm b/src/storage/netapp/ontap/restapi/mode/luns.pm index 5205d2cd7..52f55f157 100644 --- a/src/storage/netapp/ontap/restapi/mode/luns.pm +++ b/src/storage/netapp/ontap/restapi/mode/luns.pm @@ -115,17 +115,17 @@ Filter LUN name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{container_state}, %{display} +You can use the following variables: %{state}, %{container_state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{container_state}, %{display} +You can use the following variables: %{state}, %{container_state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /online/i'). -Can used special variables like: %{state}, %{container_state}, %{display} +You can use the following variables: %{state}, %{container_state}, %{display} =back diff --git a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm index 753d4931a..bfff2e735 100644 --- a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm +++ b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm @@ -118,17 +118,17 @@ Filter snapmirror name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{healthy}, %{state}, %{transfer_state}, %{display} +You can use the following variables: %{healthy}, %{state}, %{transfer_state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{healthy}, %{state}, %{transfer_state}, %{display} +You can use the following variables: %{healthy}, %{state}, %{transfer_state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{healthy} ne "true" or %{state} eq "broken_off"'). -Can used special variables like: %{healthy}, %{state}, %{transfer_state}, %{display} +You can use the following variables: %{healthy}, %{state}, %{transfer_state}, %{display} =back diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index 080639790..4a1aed3b2 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -288,17 +288,17 @@ Filter volumes by vserver name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /online/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/snmp/mode/aggregates.pm b/src/storage/netapp/ontap/snmp/mode/aggregates.pm index 78a71d933..d48a15b95 100644 --- a/src/storage/netapp/ontap/snmp/mode/aggregates.pm +++ b/src/storage/netapp/ontap/snmp/mode/aggregates.pm @@ -134,32 +134,32 @@ Filter aggregates by name. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /normal|mirrored/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--unknown-state> Set unknown threshold for state. -Can used special variables like: %{state}, %{name} +You can use the following variables: %{state}, %{name} =item B<--warning-state> Set warning threshold for state. -Can used special variables like: %{state}, %{name} +You can use the following variables: %{state}, %{name} =item B<--critical-state> Set critical threshold for state (Default: '%{state} =~ /offline/i'). -Can used special variables like: %{state}, %{name} +You can use the following variables: %{state}, %{name} =back diff --git a/src/storage/netapp/ontap/snmp/mode/clusternodes.pm b/src/storage/netapp/ontap/snmp/mode/clusternodes.pm index 640d66e02..d57d3d9a3 100644 --- a/src/storage/netapp/ontap/snmp/mode/clusternodes.pm +++ b/src/storage/netapp/ontap/snmp/mode/clusternodes.pm @@ -391,62 +391,62 @@ Filter ports by role (can be a regexp). =item B<--unknown-node-status> Set unknown threshold for status. -Can used special variables like: %{node_status}, %{node_name} +You can use the following variables: %{node_status}, %{node_name} =item B<--warning-node-status> Set warning threshold for status. -Can used special variables like: %{node_status}, %{node_name} +You can use the following variables: %{node_status}, %{node_name} =item B<--critical-node-status> Set critical threshold for status (Default: '%{node_status} eq "clusterComLost"'). -Can used special variables like: %{node_status}, %{node_name} +You can use the following variables: %{node_status}, %{node_name} =item B<--unknown-bbu-status> Set unknown threshold for status. -Can used special variables like: %{bbu_status}, %{node_name} +You can use the following variables: %{bbu_status}, %{node_name} =item B<--warning-bbu-status> Set warning threshold for status. -Can used special variables like: %{bbu_status}, %{node_name} +You can use the following variables: %{bbu_status}, %{node_name} =item B<--critical-bbu-status> Set critical threshold for status (Default: '%{bbu_status} !~ /fullyCharged|ok/i'). -Can used special variables like: %{bbu_status}, %{node_name} +You can use the following variables: %{bbu_status}, %{node_name} =item B<--unknown-port-link-status> Set unknown threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{port_id}, %{node_name} +You can use the following variables: %{admstatus}, %{opstatus}, %{port_id}, %{node_name} =item B<--warning-port-link-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{port_id}, %{node_name} +You can use the following variables: %{admstatus}, %{opstatus}, %{port_id}, %{node_name} =item B<--critical-port-link-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{port_id}, %{node_name} +You can use the following variables: %{admstatus}, %{opstatus}, %{port_id}, %{node_name} =item B<--unknown-port-health> Set unknown threshold for status. -Can used special variables like: %{health}, %{port_id}, %{node_name} +You can use the following variables: %{health}, %{port_id}, %{node_name} =item B<--warning-port-health> Set warning threshold for status (Default: '%{health} eq "degraded"'). -Can used special variables like: %{health}, %{port_id}, %{node_name} +You can use the following variables: %{health}, %{port_id}, %{node_name} =item B<--critical-port-health> Set critical threshold for status. -Can used special variables like: %{health}, %{port_id}, %{node_name} +You can use the following variables: %{health}, %{port_id}, %{node_name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/snmp/mode/failover.pm b/src/storage/netapp/ontap/snmp/mode/failover.pm index a8f97df84..fb629bb64 100644 --- a/src/storage/netapp/ontap/snmp/mode/failover.pm +++ b/src/storage/netapp/ontap/snmp/mode/failover.pm @@ -203,32 +203,32 @@ Filter name with regexp (based on serial) =item B<--unknown-cluster-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{cluster_status}, %{reason_cannot_takeover}, %{partner_status} +You can use the following variables: %{cluster_status}, %{reason_cannot_takeover}, %{partner_status} =item B<--warning-cluster-status> Set warning threshold for status (Default: '%{cluster_status} =~ /^takeover|partialGiveback/i'). -Can used special variables like: %{cluster_status}, %{reason_cannot_takeover}, %{partner_status} +You can use the following variables: %{cluster_status}, %{reason_cannot_takeover}, %{partner_status} =item B<--critical-cluster-status> Set critical threshold for status (Default: '%{cluster_status} =~ /dead|cannotTakeover/i'). -Can used special variables like: %{cluster_status}, %{reason_cannot_takeover}, %{partner_status} +You can use the following variables: %{cluster_status}, %{reason_cannot_takeover}, %{partner_status} =item B<--unknown-node-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{status}, %{reason_cannot_takeover}, %{partner_status}, %{display} +You can use the following variables: %{status}, %{reason_cannot_takeover}, %{partner_status}, %{display} =item B<--warning-node-status> Set warning threshold for status (Default: '%{status} =~ /^takeover|partialGiveback/i'). -Can used special variables like: %{status}, %{reason_cannot_takeover}, %{partner_status}, %{display} +You can use the following variables: %{status}, %{reason_cannot_takeover}, %{partner_status}, %{display} =item B<--critical-node-status> Set critical threshold for status (Default: '%{status} =~ /dead|cannotTakeover/i'). -Can used special variables like: %{status}, %{reason_cannot_takeover}, %{partner_status}, %{display} +You can use the following variables: %{status}, %{reason_cannot_takeover}, %{partner_status}, %{display} =back diff --git a/src/storage/netapp/ontap/snmp/mode/filesys.pm b/src/storage/netapp/ontap/snmp/mode/filesys.pm index 1425b7ea1..89bd19442 100644 --- a/src/storage/netapp/ontap/snmp/mode/filesys.pm +++ b/src/storage/netapp/ontap/snmp/mode/filesys.pm @@ -369,17 +369,17 @@ Check filesystem usage (volumes, snapshots and aggregates also). =item B<--unknown-vserver-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{vserver_status}, %{vserver_name} +You can use the following variables: %{vserver_status}, %{vserver_name} =item B<--warning-vserver-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{vserver_status}, %{vserver_name} +You can use the following variables: %{vserver_status}, %{vserver_name} =item B<--critical-vserver-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{vserver_status}, %{vserver_name} +You can use the following variables: %{vserver_status}, %{vserver_name} =item B<--warning-*> diff --git a/src/storage/netapp/ontap/snmp/mode/plexes.pm b/src/storage/netapp/ontap/snmp/mode/plexes.pm index 399418345..1c6189295 100644 --- a/src/storage/netapp/ontap/snmp/mode/plexes.pm +++ b/src/storage/netapp/ontap/snmp/mode/plexes.pm @@ -221,17 +221,17 @@ Filter plexes by aggregate name. =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name}, %{aggregate} +You can use the following variables: %{status}, %{name}, %{aggregate} =item B<--warning-status> Set warning threshold for status (Default: '%{status} eq "resyncing"'). -Can used special variables like: %{status}, %{name}, %{aggregate} +You can use the following variables: %{status}, %{name}, %{aggregate} =item B<--critical-status> Set critical threshold for status (Default: '%{status} eq "offline"'). -Can used special variables like: %{status}, %{name}, %{aggregate} +You can use the following variables: %{status}, %{name}, %{aggregate} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/snmp/mode/sis.pm b/src/storage/netapp/ontap/snmp/mode/sis.pm index debf7cd34..de81c55a7 100644 --- a/src/storage/netapp/ontap/snmp/mode/sis.pm +++ b/src/storage/netapp/ontap/snmp/mode/sis.pm @@ -175,17 +175,17 @@ Filter name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{lastOpError}, %{display} +You can use the following variables: %{state}, %{status}, %{lastOpError}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{lastOpError}, %{display} +You can use the following variables: %{state}, %{status}, %{lastOpError}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} eq "enabled" and %{lastOpError} !~ /-|Success/i'). -Can used special variables like: %{state}, %{status}, %{lastOpError}, %{display} +You can use the following variables: %{state}, %{status}, %{lastOpError}, %{display} =back diff --git a/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm b/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm index a69d8b7db..c21647c6d 100644 --- a/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm +++ b/src/storage/netapp/ontap/snmp/mode/snapmirrorlag.pm @@ -246,17 +246,17 @@ Example: --filter-counters='^status$' =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{state} =~ /quiesced/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} =~ /unknown|brokenOff|uninitialized/i'). -Can used special variables like: %{state}, %{display} +You can use the following variables: %{state}, %{display} =item B<--warning-lag> diff --git a/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm b/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm index 040ed0d04..4c4a11d9b 100644 --- a/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm +++ b/src/storage/netapp/ontap/snmp/mode/snapvaultusage.pm @@ -220,17 +220,17 @@ Filter snapvault name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{state}, %{status}, %{display} +You can use the following variables: %{state}, %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm b/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm index 0b4f11a0c..b9ac7d921 100644 --- a/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm +++ b/src/storage/netapp/ontap/snmp/mode/volumeoptions.pm @@ -198,32 +198,32 @@ Filter on volume status (can be a regexp). =item B<--unknown-status> Set unknown threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--unknown-options> Set warning threshold for status (Default: ''). -Can used special variables like: %{options}, %{display} +You can use the following variables: %{options}, %{display} =item B<--warning-options> Set warning threshold for status (Default: ''). -Can used special variables like: %{options}, %{display} +You can use the following variables: %{options}, %{display} =item B<--critical-options> Set critical threshold for status (Default: ''). -Can used special variables like: %{options}, %{display} +You can use the following variables: %{options}, %{display} =back diff --git a/src/storage/netapp/santricity/restapi/mode/storagecontrollers.pm b/src/storage/netapp/santricity/restapi/mode/storagecontrollers.pm index ca2602363..90e95665d 100644 --- a/src/storage/netapp/santricity/restapi/mode/storagecontrollers.pm +++ b/src/storage/netapp/santricity/restapi/mode/storagecontrollers.pm @@ -217,17 +217,17 @@ Filter controller name (can be a regexp). =item B<--unknown-controller-status> Set unknown threshold for status (Default: '%{status} =~ /unknown/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-controller-status> Set warning threshold for status (Default: '%{status} =~ /rpaParErr|degraded/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-controller-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/santricity/restapi/mode/storagepools.pm b/src/storage/netapp/santricity/restapi/mode/storagepools.pm index 790bdf7b4..ca453daea 100644 --- a/src/storage/netapp/santricity/restapi/mode/storagepools.pm +++ b/src/storage/netapp/santricity/restapi/mode/storagepools.pm @@ -200,17 +200,17 @@ Filter pool name (can be a regexp). =item B<--unknown-pool-status> Set unknown threshold for status. -Can used special variables like: %{raid_status}, %{state}, %{display} +You can use the following variables: %{raid_status}, %{state}, %{display} =item B<--warning-pool-status> Set warning threshold for status (Default: '%{raid_status} =~ /degraded/i'). -Can used special variables like: %{raid_status}, %{state}, %{display} +You can use the following variables: %{raid_status}, %{state}, %{display} =item B<--critical-pool-status> Set critical threshold for status (Default: '%{raid_status} =~ /failed/i'). -Can used special variables like: %{raid_status}, %{state}, %{display} +You can use the following variables: %{raid_status}, %{state}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/santricity/restapi/mode/storagesystems.pm b/src/storage/netapp/santricity/restapi/mode/storagesystems.pm index 22d5a3f49..073bae8ac 100644 --- a/src/storage/netapp/santricity/restapi/mode/storagesystems.pm +++ b/src/storage/netapp/santricity/restapi/mode/storagesystems.pm @@ -161,17 +161,17 @@ Filter storage name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{state}, %{display} +You can use the following variables: %{status}, %{state}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /needsAttn/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/santricity/restapi/mode/storagevolumes.pm b/src/storage/netapp/santricity/restapi/mode/storagevolumes.pm index 1ca983129..1627a340f 100644 --- a/src/storage/netapp/santricity/restapi/mode/storagevolumes.pm +++ b/src/storage/netapp/santricity/restapi/mode/storagevolumes.pm @@ -203,17 +203,17 @@ Filter volume name (can be a regexp). =item B<--unknown-volume-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-volume-status> Set warning threshold for status (Default: '%{status} =~ /degraded/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-volume-status> Set critical threshold for status (Default: '%{status} =~ /failed/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/nimble/restapi/mode/arrays.pm b/src/storage/nimble/restapi/mode/arrays.pm index a9c331c5a..94f573323 100644 --- a/src/storage/nimble/restapi/mode/arrays.pm +++ b/src/storage/nimble/restapi/mode/arrays.pm @@ -182,17 +182,17 @@ Filter array name (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /unreachable/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/nimble/restapi/mode/volumes.pm b/src/storage/nimble/restapi/mode/volumes.pm index a04efa1b4..1b56918b5 100644 --- a/src/storage/nimble/restapi/mode/volumes.pm +++ b/src/storage/nimble/restapi/mode/volumes.pm @@ -202,17 +202,17 @@ Filter volumes by replication role (can be a regexp). =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{state}, %{space_level_usage}, %{display} +You can use the following variables: %{state}, %{space_level_usage}, %{display} =item B<--warning-status> Set warning threshold for status (Default: '%{space_usage_level} =~ /warning/'). -Can used special variables like: %{state}, %{space_level_usage}, %{display} +You can use the following variables: %{state}, %{space_level_usage}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{state} !~ /online/i || %{space_usage_level} =~ /critical/'). -Can used special variables like: %{state}, %{space_level_usage}, %{display} +You can use the following variables: %{state}, %{space_level_usage}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/oracle/zs/restapi/mode/pools.pm b/src/storage/oracle/zs/restapi/mode/pools.pm index 5bb237146..f1416a2ec 100644 --- a/src/storage/oracle/zs/restapi/mode/pools.pm +++ b/src/storage/oracle/zs/restapi/mode/pools.pm @@ -175,17 +175,17 @@ Filter pool name (can be a regexp). =item B<--unknown-status> Set unknon threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /online|exported/i'). -Can used special variables like: %{status}, %{display} +You can use the following variables: %{status}, %{display} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/purestorage/flasharray/legacy/restapi/mode/alarms.pm b/src/storage/purestorage/flasharray/legacy/restapi/mode/alarms.pm index 0200fd647..e549d0c92 100644 --- a/src/storage/purestorage/flasharray/legacy/restapi/mode/alarms.pm +++ b/src/storage/purestorage/flasharray/legacy/restapi/mode/alarms.pm @@ -176,12 +176,12 @@ Filter by category name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /warning/i') -Can used special variables like: %{category}, %{code}, %{severity}, %{opened}, %{event}, %{component_name} +You can use the following variables: %{category}, %{code}, %{severity}, %{opened}, %{event}, %{component_name} =item B<--critical-status> Set critical threshold for status (Default: '%{severity} =~ /critical/i'). -Can used special variables like: %{category}, %{code}, %{severity}, %{opened}, %{event}, %{component_name} +You can use the following variables: %{category}, %{code}, %{severity}, %{opened}, %{event}, %{component_name} =item B<--memory> diff --git a/src/storage/purestorage/flasharray/v2/restapi/mode/alerts.pm b/src/storage/purestorage/flasharray/v2/restapi/mode/alerts.pm index 215a9765c..89a7ba4cf 100644 --- a/src/storage/purestorage/flasharray/v2/restapi/mode/alerts.pm +++ b/src/storage/purestorage/flasharray/v2/restapi/mode/alerts.pm @@ -166,12 +166,12 @@ Filter by category name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{state} ne "closed" and %{severity} =~ /warning/i') -Can used special variables like: %{category}, %{code}, %{severity}, %{opened}, %{state}, %{issue}, %{component_name} +You can use the following variables: %{category}, %{code}, %{severity}, %{opened}, %{state}, %{issue}, %{component_name} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "closed" and %{severity} =~ /critical/i'). -Can used special variables like: %{category}, %{code}, %{severity}, %{opened}, %{state}, %{issue}, %{component_name} +You can use the following variables: %{category}, %{code}, %{severity}, %{opened}, %{state}, %{issue}, %{component_name} =item B<--memory> diff --git a/src/storage/purestorage/flashblade/v2/restapi/mode/alerts.pm b/src/storage/purestorage/flashblade/v2/restapi/mode/alerts.pm index 0706ca44f..174772ecc 100644 --- a/src/storage/purestorage/flashblade/v2/restapi/mode/alerts.pm +++ b/src/storage/purestorage/flashblade/v2/restapi/mode/alerts.pm @@ -161,12 +161,12 @@ Check alerts. =item B<--warning-status> Set warning threshold for status (Default: '%{state} ne "closed" and %{severity} =~ /warning/i') -Can used special variables like: %{code}, %{severity}, %{opened}, %{state}, %{component_name} +You can use the following variables: %{code}, %{severity}, %{opened}, %{state}, %{component_name} =item B<--critical-status> Set critical threshold for status (Default: '%{state} ne "closed" and %{severity} =~ /critical/i'). -Can used special variables like: %{code}, %{severity}, %{opened}, %{state}, %{component_name} +You can use the following variables: %{code}, %{severity}, %{opened}, %{state}, %{component_name} =item B<--memory> diff --git a/src/storage/qnap/snmp/mode/pools.pm b/src/storage/qnap/snmp/mode/pools.pm index 45bcf2e27..80238b029 100644 --- a/src/storage/qnap/snmp/mode/pools.pm +++ b/src/storage/qnap/snmp/mode/pools.pm @@ -258,17 +258,17 @@ Filter pools by name (can be a regexp). =item B<--unknown-pool-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-pool-status> Set warning threshold for status (Default: '%{status} =~ /degraded|warning/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-pool-status> Set critical threshold for status (Default: '%{status} =~ /error|critical/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/qnap/snmp/mode/upgrade.pm b/src/storage/qnap/snmp/mode/upgrade.pm index e247ea6a5..d209b030f 100644 --- a/src/storage/qnap/snmp/mode/upgrade.pm +++ b/src/storage/qnap/snmp/mode/upgrade.pm @@ -99,12 +99,12 @@ Check upgrade status (only works with QTS OS). =item B<--warning-status> Set warning threshold for status (Default : '%{upgrade} eq "available"'). -Can used special variables like: %{model}, %{version}, %{upgrade} +You can use the following variables: %{model}, %{version}, %{upgrade} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{model}, %{version}, %{upgrade} +You can use the following variables: %{model}, %{version}, %{upgrade} =back diff --git a/src/storage/qnap/snmp/mode/volumes.pm b/src/storage/qnap/snmp/mode/volumes.pm index fa3e8df65..903bd9fcb 100644 --- a/src/storage/qnap/snmp/mode/volumes.pm +++ b/src/storage/qnap/snmp/mode/volumes.pm @@ -270,17 +270,17 @@ Force to use legacy counters. Should be used when EX/QTS counters are buggy. =item B<--unknown-volume-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-volume-status> Set warning threshold for status (Default: '%{status} =~ /degraded|warning/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--critical-volume-status> Set critical threshold for status (Default: '%{status} =~ /critical/i'). -Can used special variables like: %{status}, %{name} +You can use the following variables: %{status}, %{name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/quantum/dxi/ssh/mode/compaction.pm b/src/storage/quantum/dxi/ssh/mode/compaction.pm index edc57a876..df9005739 100644 --- a/src/storage/quantum/dxi/ssh/mode/compaction.pm +++ b/src/storage/quantum/dxi/ssh/mode/compaction.pm @@ -173,12 +173,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{compaction_status} +You can use the following variables: %{compaction_status} =item B<--critical-status> Set critical threshold for status (Default: '%{compaction_status} !~ /ready/i'). -Can used special variables like: %{compaction_status} +You can use the following variables: %{compaction_status} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/quantum/dxi/ssh/mode/dedupnas.pm b/src/storage/quantum/dxi/ssh/mode/dedupnas.pm index 0945be108..57d20604f 100644 --- a/src/storage/quantum/dxi/ssh/mode/dedupnas.pm +++ b/src/storage/quantum/dxi/ssh/mode/dedupnas.pm @@ -201,12 +201,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: '%{state} !~ /Enabled/i'). -Can used special variables like: %{status}, %{state}, %{duration}, %{percent_complete}. +You can use the following variables: %{status}, %{state}, %{duration}, %{percent_complete}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}, %{state}, %{duration}, %{percent_complete}. +You can use the following variables: %{status}, %{state}, %{duration}, %{percent_complete}. =item B<--warning-*> B<--critical-*> diff --git a/src/storage/quantum/dxi/ssh/mode/dedupvtl.pm b/src/storage/quantum/dxi/ssh/mode/dedupvtl.pm index 9ef08349a..6f37fe8d4 100644 --- a/src/storage/quantum/dxi/ssh/mode/dedupvtl.pm +++ b/src/storage/quantum/dxi/ssh/mode/dedupvtl.pm @@ -202,12 +202,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: '%{state} !~ /Enabled/i'). -Can used special variables like: %{status}, %{state}, %{duration}, %{percent_complete}. +You can use the following variables: %{status}, %{state}, %{duration}, %{percent_complete}. =item B<--critical-status> Set critical threshold for status (Default: ''). -Can used special variables like: %{status}, %{state}, %{duration}, %{percent_complete}. +You can use the following variables: %{status}, %{state}, %{duration}, %{percent_complete}. =item B<--warning-*> B<--critical-*> diff --git a/src/storage/quantum/dxi/ssh/mode/health.pm b/src/storage/quantum/dxi/ssh/mode/health.pm index 740956449..2824ca20e 100644 --- a/src/storage/quantum/dxi/ssh/mode/health.pm +++ b/src/storage/quantum/dxi/ssh/mode/health.pm @@ -119,12 +119,12 @@ Check health status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{name}, %{status}, %{state} +You can use the following variables: %{name}, %{status}, %{state} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Ready|Success/i'). -Can used special variables like: %{name}, %{status}, %{state} +You can use the following variables: %{name}, %{status}, %{state} =back diff --git a/src/storage/quantum/dxi/ssh/mode/hostbusadapterstatus.pm b/src/storage/quantum/dxi/ssh/mode/hostbusadapterstatus.pm index bfdd45b0d..0277f0760 100644 --- a/src/storage/quantum/dxi/ssh/mode/hostbusadapterstatus.pm +++ b/src/storage/quantum/dxi/ssh/mode/hostbusadapterstatus.pm @@ -118,12 +118,12 @@ Check hostbus adapters status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Normal/i'). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =back diff --git a/src/storage/quantum/dxi/ssh/mode/network.pm b/src/storage/quantum/dxi/ssh/mode/network.pm index cbef07afa..8b898eeb2 100644 --- a/src/storage/quantum/dxi/ssh/mode/network.pm +++ b/src/storage/quantum/dxi/ssh/mode/network.pm @@ -119,12 +119,12 @@ Check network ports status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Up/i'). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =back diff --git a/src/storage/quantum/dxi/ssh/mode/reclamation.pm b/src/storage/quantum/dxi/ssh/mode/reclamation.pm index 6aea623da..36b1164a8 100644 --- a/src/storage/quantum/dxi/ssh/mode/reclamation.pm +++ b/src/storage/quantum/dxi/ssh/mode/reclamation.pm @@ -186,12 +186,12 @@ Example: --filter-counters='status' =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{reclamation_status} +You can use the following variables: %{reclamation_status} =item B<--critical-status> Set critical threshold for status (Default: '%{reclamation_status} !~ /ready/i'). -Can used special variables like: %{reclamation_status} +You can use the following variables: %{reclamation_status} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/quantum/dxi/ssh/mode/storagearraystatus.pm b/src/storage/quantum/dxi/ssh/mode/storagearraystatus.pm index 384db12dc..e14f8e82d 100644 --- a/src/storage/quantum/dxi/ssh/mode/storagearraystatus.pm +++ b/src/storage/quantum/dxi/ssh/mode/storagearraystatus.pm @@ -112,12 +112,12 @@ Check storage array status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Normal/i'). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =back diff --git a/src/storage/quantum/dxi/ssh/mode/systemstatus.pm b/src/storage/quantum/dxi/ssh/mode/systemstatus.pm index 838fed8c7..f45d4d3d2 100644 --- a/src/storage/quantum/dxi/ssh/mode/systemstatus.pm +++ b/src/storage/quantum/dxi/ssh/mode/systemstatus.pm @@ -123,12 +123,12 @@ Check system board status. =item B<--warning-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =item B<--critical-status> Set critical threshold for status (Default: '%{status} !~ /Normal/i'). -Can used special variables like: %{name}, %{status} +You can use the following variables: %{name}, %{status} =back diff --git a/src/storage/synology/snmp/mode/ha.pm b/src/storage/synology/snmp/mode/ha.pm index eef814674..cb998cedc 100644 --- a/src/storage/synology/snmp/mode/ha.pm +++ b/src/storage/synology/snmp/mode/ha.pm @@ -132,17 +132,17 @@ Example: --filter-counters='^status$' =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{cluster_status}, %{heartbeat_status}, %{active_node_name}, %{passive_node_name} +You can use the following variables: %{cluster_status}, %{heartbeat_status}, %{active_node_name}, %{passive_node_name} =item B<--warning-status> Set warning threshold for status (Default: '%{cluster_status} =~ /warning/i || %{heartbeat_status} =~ /abnormal/i'). -Can used special variables like: %{cluster_status}, %{heartbeat_status}, %{active_node_name}, %{passive_node_name} +You can use the following variables: %{cluster_status}, %{heartbeat_status}, %{active_node_name}, %{passive_node_name} =item B<--critical-status> Set critical threshold for status (Default: '%{cluster_status} =~ /critical/i || %{heartbeat_status} =~ /disconnected/i'). -Can used special variables like: %{cluster_status}, %{heartbeat_status}, %{active_node_name}, %{passive_node_name} +You can use the following variables: %{cluster_status}, %{heartbeat_status}, %{active_node_name}, %{passive_node_name} =item B<--warning-*> B<--critical-*> diff --git a/src/storage/synology/snmp/mode/upgrade.pm b/src/storage/synology/snmp/mode/upgrade.pm index fa4e5dc3b..c89d8739b 100644 --- a/src/storage/synology/snmp/mode/upgrade.pm +++ b/src/storage/synology/snmp/mode/upgrade.pm @@ -104,12 +104,12 @@ Check upgrade status =item B<--warning-status> Set warning threshold for status (Default : '%{upgrade} ne "unavailable"'). -Can used special variables like: %{model}, %{version}, %{upgrade} +You can use the following variables: %{model}, %{version}, %{upgrade} =item B<--critical-status> Set critical threshold for status. -Can used special variables like: %{model}, %{version}, %{upgrade} +You can use the following variables: %{model}, %{version}, %{upgrade} =back diff --git a/src/storage/wd/nas/snmp/mode/hardware.pm b/src/storage/wd/nas/snmp/mode/hardware.pm index bbb063a42..4f4686b1f 100644 --- a/src/storage/wd/nas/snmp/mode/hardware.pm +++ b/src/storage/wd/nas/snmp/mode/hardware.pm @@ -204,12 +204,12 @@ Check hardware. =item B<--warning-fan-status> Set warning threshold for status (Default : '%{status} ne "running"'). -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--critical-fan-status> Set critical threshold for status. -Can used special variables like: %{status} +You can use the following variables: %{status} =item B<--warning-*> B<--critical-*> From b659c46e054ed6207a062bc83ce40e219507a7e0 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 2 Jun 2023 19:51:49 +0200 Subject: [PATCH 439/447] (plugin) network::cisco::standard::snmp - mode environment undefined module name (#4441) --- .../common/cisco/standard/snmp/mode/components/module.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/centreon/common/cisco/standard/snmp/mode/components/module.pm b/src/centreon/common/cisco/standard/snmp/mode/components/module.pm index d4c842d13..e36d3e691 100644 --- a/src/centreon/common/cisco/standard/snmp/mode/components/module.pm +++ b/src/centreon/common/cisco/standard/snmp/mode/components/module.pm @@ -76,7 +76,8 @@ sub check { $oid =~ /\.([0-9]+)$/; my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_cefcModuleOperStatus}, instance => $instance); - my $module_descr = $self->{results}->{$self->{physical_name} }->{ $self->{physical_name} . '.' . $instance }; + my $module_descr = defined($self->{results}->{ $self->{physical_name} }->{ $self->{physical_name} . '.' . $instance }) ? + $self->{results}->{ $self->{physical_name} }->{ $self->{physical_name} . '.' . $instance } : 'n/a'; next if ($self->check_filter(section => 'module', instance => $instance, name => $module_descr)); From abc3ff1c87a8bdf0ff85de16253348128e7846b7 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 2 Jun 2023 20:10:59 +0200 Subject: [PATCH 440/447] (plugin) network::nokia::timos::snmp - mode hardware fix undefined value (#4444) --- src/network/nokia/timos/snmp/mode/hardware.pm | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/network/nokia/timos/snmp/mode/hardware.pm b/src/network/nokia/timos/snmp/mode/hardware.pm index e23cc01d2..64b3c5a92 100644 --- a/src/network/nokia/timos/snmp/mode/hardware.pm +++ b/src/network/nokia/timos/snmp/mode/hardware.pm @@ -50,7 +50,7 @@ sub set_system { ['preExtension', 'OK'] ] }; - + $self->{components_path} = 'network::nokia::timos::snmp::mode::components'; $self->{components_module} = ['entity']; } @@ -168,35 +168,45 @@ sub check { next if ($oid !~ /^$mapping->{tmnxHwName}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); - + next if ($self->check_filter(section => 'entity', instance => $result->{tmnxHwClass} . '.' . $instance)); - + $self->{components}->{entity}->{total}++; - $self->{output}->output_add(long_msg => sprintf("%s '%s' status is '%s' [instance = %s, temperature = %s]", - $result->{tmnxHwClass}, $result->{tmnxHwName}, - $result->{tmnxHwOperState}, $result->{tmnxHwClass} . '.' . $instance, - $result->{tmnxHwTempSensor} eq 'true' ? $result->{tmnxHwTemperature} : '-')); + $self->{output}->output_add( + long_msg => sprintf( + "%s '%s' status is '%s' [instance = %s, temperature = %s]", + $result->{tmnxHwClass}, $result->{tmnxHwName}, + $result->{tmnxHwOperState}, $result->{tmnxHwClass} . '.' . $instance, + $result->{tmnxHwTempSensor} eq 'true' ? $result->{tmnxHwTemperature} : '-' + ) + ); $exit = $self->get_severity(label => 'default', section => 'entity', instance => $result->{tmnxHwClass} . '.' . $instance, value => $result->{tmnxHwOperState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("%s '%s' status is '%s'", $result->{tmnxHwClass}, $result->{tmnxHwName}, $result->{tmnxHwOperState})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("%s '%s' status is '%s'", $result->{tmnxHwClass}, $result->{tmnxHwName}, $result->{tmnxHwOperState})); } - + next if ($result->{tmnxHwTempSensor} eq 'false'); - ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $result->{tmnxHwClass} . '.' . $instance,, value => $result->{tmnxHwTemperature}); + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $result->{tmnxHwClass} . '.' . $instance, value => $result->{tmnxHwTemperature}); if ($checked == 0 && $result->{tmnxHwTempThreshold} != -1 ) { $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $result->{tmnxHwClass} . '.' . $instance, value => $result->{tmnxHwTempThreshold}); - $exit = $self->{perfdata}->threshold_check(value => $result->{slHdwTempSensorCurrentTemp}, threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }]); + $exit = $self->{perfdata}->threshold_check(value => $result->{tmnxHwTemperature}, threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }]); $warn = undef; $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-temperature-instance-' . $result->{tmnxHwClass} . '.' . $instance); } - + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("%s '%s' temperature is '%s' C", $result->{tmnxHwClass}, - $result->{tmnxHwName}, $result->{tmnxHwTemperature})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf( + "%s '%s' temperature is '%s' C", $result->{tmnxHwClass}, + $result->{tmnxHwName}, $result->{tmnxHwTemperature} + ) + ); } + $self->{output}->perfdata_add( label => 'temperature', unit => 'C', nlabel => 'hardware.entity.temperature.celsius', From 4f8e3a2ea98634433e26f0e67696fac9cfd2e425 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 2 Jun 2023 20:11:24 +0200 Subject: [PATCH 441/447] (plugin) hardware::sensors::apc::snmp - mode sensors undefined humidity value (#4446) --- src/hardware/sensors/apc/snmp/mode/components/humidity.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/sensors/apc/snmp/mode/components/humidity.pm b/src/hardware/sensors/apc/snmp/mode/components/humidity.pm index fa955c468..b1c48ccc2 100644 --- a/src/hardware/sensors/apc/snmp/mode/components/humidity.pm +++ b/src/hardware/sensors/apc/snmp/mode/components/humidity.pm @@ -95,7 +95,7 @@ sub check_module_humidity { ); } - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{temp}); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{humidity}); if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit2, From 1b79704575d9574b1a716eae347a0ecefd3e22ec Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 6 Jun 2023 10:26:48 +0200 Subject: [PATCH 442/447] (plugin) apps::protocols::snmp - add snmp cache system (#4443) --- src/apps/protocols/snmp/mode/cache.pm | 115 ++++++++++++++++++++++ src/apps/protocols/snmp/plugin.pm | 1 + src/centreon/plugins/snmp.pm | 133 +++++++++++++++++++++++++- 3 files changed, 245 insertions(+), 4 deletions(-) create mode 100644 src/apps/protocols/snmp/mode/cache.pm diff --git a/src/apps/protocols/snmp/mode/cache.pm b/src/apps/protocols/snmp/mode/cache.pm new file mode 100644 index 000000000..73ea1578b --- /dev/null +++ b/src/apps/protocols/snmp/mode/cache.pm @@ -0,0 +1,115 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::protocols::snmp::mode::cache; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'file:s' => { name => 'file' }, + 'snmpwalk:s@' => { name => 'snmpwalk' }, + 'snmpget:s@' => { name => 'snmpget' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{file}) || $self->{option_results}->{file} eq '') { + $self->{output}->add_option_msg(short_msg => "Missing parameter --file"); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my $snmp_datas = {}; + if (defined($self->{option_results}->{snmpwalk})) { + foreach my $oid (@{$self->{option_results}->{snmpwalk}}) { + my $result = $options{snmp}->get_table(oid => $oid); + $snmp_datas = { %$snmp_datas, %$result }; + } + } + + if (defined($self->{option_results}->{snmpget})) { + my $result = $options{snmp}->get_leef(oids => $self->{option_results}->{snmpget}); + $snmp_datas = { %$snmp_datas, %$result }; + } + + my $json; + eval { + $json = JSON::XS->new->encode($snmp_datas); + }; + + my $fh; + if (!open($fh, '>', $self->{option_results}->{file})) { + $self->{output}->add_option_msg(short_msg => "Can't open file '$self->{option_results}->{file}': $!"); + $self->{output}->option_exit(); + } + print $fh $json; + close($fh); + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'SNMP cache file created' + ); + + $self->{output}->display(force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Cache SNMP datas in a JSON cache file. + +=over 8 + +=item B<--file> + +JSON cache file path. + +=item B<--snmpget> + +Retrieve a management value. + +=item B<--snmpwalk> + +Retrieve a subtree of management values. + +=back + +=cut diff --git a/src/apps/protocols/snmp/plugin.pm b/src/apps/protocols/snmp/plugin.pm index 3357c091d..9198225de 100644 --- a/src/apps/protocols/snmp/plugin.pm +++ b/src/apps/protocols/snmp/plugin.pm @@ -30,6 +30,7 @@ sub new { bless $self, $class; $self->{modes} = { + 'cache' => 'apps::protocols::snmp::mode::cache', 'collection' => 'apps::protocols::snmp::mode::collection', 'discovery' => 'snmp_standard::mode::discovery', 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', diff --git a/src/centreon/plugins/snmp.pm b/src/centreon/plugins/snmp.pm index 06eb1c9bf..55aad3490 100644 --- a/src/centreon/plugins/snmp.pm +++ b/src/centreon/plugins/snmp.pm @@ -22,6 +22,7 @@ package centreon::plugins::snmp; use strict; use warnings; +use centreon::plugins::misc; use SNMP; use Socket; use POSIX; @@ -54,6 +55,7 @@ sub new { 'maxrepetitions:s' => { name => 'maxrepetitions', default => 50 }, 'subsetleef:s' => { name => 'subsetleef', default => 50 }, 'subsettable:s' => { name => 'subsettable', default => 100 }, + 'snmp-cache-file:s' => { name => 'snmp_cache_file' }, 'snmp-autoreduce:s' => { name => 'snmp_autoreduce' }, 'snmp-force-getnext' => { name => 'snmp_force_getnext' }, 'snmp-username:s' => { name => 'snmp_security_name' }, @@ -221,6 +223,24 @@ sub autoreduce_leef { return 0; } +sub get_leef_cache { + my ($self, %options) = @_; + + my $results = {}; + foreach my $oid (@{$options{oids}}) { + if (defined($self->{snmp_cache}->{$oid})) { + $results->{$oid} = $self->{snmp_cache}->{$oid}; + } + } + + if ($options{nothing_quit} == 1 && scalar(keys %$results) <= 0) { + $self->{output}->add_option_msg(short_msg => 'SNMP GET Request: Cant get a single value.'); + $self->{output}->option_exit(exit_litteral => $self->{snmp_errors_exit}); + } + + return $results; +} + sub get_leef { my ($self, %options) = @_; # $options{dont_quit} = integer @@ -247,6 +267,10 @@ sub get_leef { @{$self->{oids_loaded}} = (); } + if ($self->{use_snmp_cache} == 1) { + return $self->get_leef_cache(oids => $options{oids}, nothing_quit => $nothing_quit); + } + my $results = {}; $self->{array_ref_ar} = []; my $subset_current = 0; @@ -396,6 +420,43 @@ sub multiple_find_bigger { return $getting->{pop(@values)}; } +sub get_multiple_table_cache { + my ($self, %options) = @_; + + my $results = {}; + foreach my $entry (@{$options{oids}}) { + my $result = $self->get_table_cache( + oid => $entry->{oid}, + start => $entry->{start}, + end => $entry->{end}, + nothing_quit => 0 + ); + if ($options{return_type} == 0) { + $results->{ $entry->{oid} } = $result; + } else { + $results = { %$results, %$result }; + } + } + + my $total = 0; + if ($options{nothing_quit} == 1) { + if ($options{return_type} == 1) { + $total = scalar(keys %$results); + } else { + foreach (keys %$results) { + $total += scalar(keys %{$results->{$_}}); + } + } + + if ($total == 0) { + $self->{output}->add_option_msg(short_msg => 'SNMP Table Request: Cant get a single value.'); + $self->{output}->option_exit(exit_litteral => $self->{snmp_errors_exit}); + } + } + + return $results; +} + sub get_multiple_table { my ($self, %options) = @_; # $options{dont_quit} = integer @@ -408,6 +469,14 @@ sub get_multiple_table { my ($nothing_quit) = (defined($options{nothing_quit}) && $options{nothing_quit} == 1) ? 1 : 0; $self->set_error(); + if ($self->{use_snmp_cache} == 1) { + return $self->get_multiple_table_cache( + oids => $options{oids}, + return_type => $return_type, + nothing_quit => $nothing_quit + ); + } + my $working_oids = {}; my $results = {}; # Check overlap @@ -429,7 +498,7 @@ sub get_multiple_table { } if ($return_type == 0) { - $results->{$entry->{oid}} = {}; + $results->{ $entry->{oid} } = {}; } } @@ -560,6 +629,29 @@ sub get_multiple_table { return $results; } +sub get_table_cache { + my ($self, %options) = @_; + + my $branch = defined($options{start}) ? $options{start} : $options{oid}; + + my $results = {}; + foreach my $oid ($self->oid_lex_sort(keys %{$self->{snmp_cache}})) { + if ($oid =~ /^$branch\./) { + $results->{$oid} = $self->{snmp_cache}->{$oid}; + if (defined($options{end}) && $self->check_oid_up(current => $oid, end => $options{end})) { + last; + } + } + } + + if ($options{nothing_quit} == 1 && scalar(keys %$results) <= 0) { + $self->{output}->add_option_msg(short_msg => 'SNMP Table Request: Cant get a single value.'); + $self->{output}->option_exit(exit_litteral => $self->{snmp_errors_exit}); + } + + return $results; +} + sub get_table { my ($self, %options) = @_; # $options{dont_quit} = integer @@ -578,6 +670,15 @@ sub get_table { $options{end} = $self->clean_oid($options{end}); } + if ($self->{use_snmp_cache} == 1) { + return $self->get_table_cache( + oid => $options{oid}, + start => $options{start}, + end => $options{end}, + nothing_quit => $nothing_quit + ); + } + # we use a medium (UDP have a PDU limit. SNMP protcol cant send multiples for one request) # So we need to manage # It's for "bulk". We ask 50 next values. If you set 1, it's like a getnext (snmp v1) @@ -597,7 +698,7 @@ sub get_table { $self->{output}->option_exit(exit_litteral => $self->{snmp_errors_exit}); } - my $main_indice = $1 . "." . $2; + my $main_indice = $1 . '.' . $2; my $results = {}; # Quit if base not the same or 'ENDOFMIBVIEW' value @@ -751,7 +852,28 @@ sub check_oid_up { sub check_options { my ($self, %options) = @_; - # $options{option_results} = ref to options result + + $self->{snmp_errors_exit} = $options{option_results}->{snmp_errors_exit}; + + $self->{use_snmp_cache} = 0; + if (defined($options{option_results}->{snmp_cache_file}) && $options{option_results}->{snmp_cache_file} ne '') { + centreon::plugins::misc::mymodule_load( + output => $self->{output}, + module => 'JSON::XS', + error_msg => "Cannot load module 'JSON::XS'." + ); + my $content = centreon::plugins::misc::slurp_file(output => $self->{output}, file => $options{option_results}->{snmp_cache_file}); + eval { + $self->{snmp_cache} = JSON::XS->new->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json cache file: $@"); + $self->{output}->option_exit(); + } + + $self->{use_snmp_cache} = 1; + return ; + } if (!defined($options{option_results}->{host})) { $self->{output}->add_option_msg(short_msg => 'Missing parameter --hostname.'); @@ -768,7 +890,6 @@ sub check_options { $self->{maxrepetitions} = $options{option_results}->{maxrepetitions}; $self->{subsetleef} = (defined($options{option_results}->{subsetleef}) && $options{option_results}->{subsetleef} =~ /^[0-9]+$/) ? $options{option_results}->{subsetleef} : 50; $self->{subsettable} = (defined($options{option_results}->{subsettable}) && $options{option_results}->{subsettable} =~ /^[0-9]+$/) ? $options{option_results}->{subsettable} : 100; - $self->{snmp_errors_exit} = $options{option_results}->{snmp_errors_exit}; $self->{snmp_autoreduce} = 0; $self->{snmp_autoreduce_divisor} = 2; if (defined($options{option_results}->{snmp_autoreduce})) { @@ -1023,6 +1144,10 @@ Auto reduce SNMP request size in case of SNMP errors (By default, the divisor is Use snmp getnext function (even in snmp v2c and v3). +=item B<--snmp-cache-file> + +Use SNMP cache file. + =item B<--snmp-username> Security name (only for SNMP v3). From 47bd26dbdae9f2836da9880fa76ec863c0334370 Mon Sep 17 00:00:00 2001 From: omercier <32134301+omercier@users.noreply.github.com> Date: Wed, 7 Jun 2023 09:27:48 +0200 Subject: [PATCH 443/447] Improve most used helps (#4453) --- src/centreon/plugins/dbi.pm | 16 +++--- src/centreon/plugins/http.pm | 10 ++-- src/centreon/plugins/multi.pm | 7 +-- src/centreon/plugins/output.pm | 41 ++++++++++----- src/centreon/plugins/script.pm | 17 +++--- src/centreon/plugins/script_custom.pm | 2 +- src/centreon/plugins/script_simple.pm | 2 +- src/centreon/plugins/script_snmp.pm | 2 +- src/centreon/plugins/script_sql.pm | 9 ++-- src/centreon/plugins/script_wsman.pm | 2 +- src/centreon/plugins/snmp.pm | 74 ++++++++++++++++----------- src/centreon/plugins/ssh.pm | 4 +- 12 files changed, 108 insertions(+), 78 deletions(-) diff --git a/src/centreon/plugins/dbi.pm b/src/centreon/plugins/dbi.pm index 85d0f2923..ff61fa1f5 100644 --- a/src/centreon/plugins/dbi.pm +++ b/src/centreon/plugins/dbi.pm @@ -365,32 +365,34 @@ dbi class =item B<--datasource> -Datasource (required. Depends of database server). +Database server information, mandatory if the server's address and port are not +defined in the corresponding options. The syntax depends on the database type. =item B<--username> -Database username. +User name used to connect to the database. =item B<--password> -Database password. +Password for the defined user name. =item B<--connect-options> -Add options in database connect. +Add connection options for the DBI connect method. Format: name=value,name2=value2,... =item B<--connect-query> -Execute a query just after connection. +Execute a query just after the connection. =item B<--sql-errors-exit> -Exit code for DB Errors (default: unknown) +Expected status in case of DB error or timeout. +Possible values are warning, critical and unknown (default). =item B<--timeout> -Timeout in seconds for connection +Timeout in seconds for connection. =item B<--exec-timeout> diff --git a/src/centreon/plugins/http.pm b/src/centreon/plugins/http.pm index 12ce5ba75..225e642e3 100644 --- a/src/centreon/plugins/http.pm +++ b/src/centreon/plugins/http.pm @@ -256,20 +256,20 @@ Set the address you want to connect to. Useful if hostname is only a vhost, to a =item B<--proxyurl> -Proxy URL +Proxy URL. Eg: http://my.proxy:3128 =item B<--proxypac> -Proxy pac file (can be a URL or local file) +Proxy pac file (can be a URL or a local file). =item B<--insecure> -Insecure SSL connections. +Accept insecure SSL connections. =item B<--http-backend> -Set the backend used (Default: 'lwp') -For curl: --http-backend=curl +Perl library to use for HTTP transactions. +Possible values are: lwp (default) and curl. =back diff --git a/src/centreon/plugins/multi.pm b/src/centreon/plugins/multi.pm index f2c8a9e17..877b90b5a 100644 --- a/src/centreon/plugins/multi.pm +++ b/src/centreon/plugins/multi.pm @@ -108,13 +108,14 @@ Check multiple modes at once. =item B<--modes-exec> -Which modes to select (separated by coma). +Modes to use, separated by commas. Example for linux: --modes-exec=cpu,memory,storage,interfaces =item B<--option-mode> -Set options for a specifi mode (can be multiple). -Example interfaces and storage snmp: +Define options for the modes selected in --modes-exec. +The option can be used several times. +E.g.: to define two options for the interfaces mode and one for the storage mode: --option-mode='interfaces,--statefile-dir=/tmp' --option-mode='interfaces,--add-traffic' --option-mode='storage,--statefile-dir=/tmp' =back diff --git a/src/centreon/plugins/output.pm b/src/centreon/plugins/output.pm index b2ff3dca3..1b9afc7b7 100644 --- a/src/centreon/plugins/output.pm +++ b/src/centreon/plugins/output.pm @@ -1553,11 +1553,11 @@ Common examples: =over 4 -Change storage free perfdata in used: --change-perfdata=free,used,invert() +Convert storage free perfdata into used: --change-perfdata=free,used,invert() -Change storage free perfdata in used: --change-perfdata=used,free,invert() +Convert storage free perfdata into used: --change-perfdata=used,free,invert() -Scale traffic values automaticaly: --change-perfdata=traffic,,scale(auto) +Scale traffic values automatically: --change-perfdata=traffic,,scale(auto) Scale traffic values in Mbps: --change-perfdata=traffic_in,,scale(Mbps),mbps @@ -1567,8 +1567,14 @@ Change traffic values in percent: --change-perfdata=traffic_in,,percent() =item B<--extend-perfdata-group> -Extend perfdata from multiple perfdatas (methods in target are: min, max, average, sum) -Syntax: --extend-perfdata-group=searchlabel,newlabel,target[,[newuom],[min],[max]] +Add new aggregated metrics (min, max, average or sum) for groups of metrics defined by a regex match on the metrics' names. +Syntax: --extend-perfdata-group=regex,namesofnewmetrics,calculation[,[newuom],[min],[max]] +regex: regular expression +namesofnewmetrics: how the new metrics' names are composed (can use $1, $2... for groups defined by () in regex). +calculation: how the values of the new metrics should be calculated +newuom (optional): unit of measure for the new metrics +min (optional): lowest value the metrics can reach +max (optional): highest value the metrics can reach Common examples: @@ -1614,40 +1620,47 @@ and an output. =item B<--output-ignore-label> -Remove the status label from the beginning of the output. +Remove the status label ("OK:", "WARNING:", "UNKNOWN:", CRITICAL:") from the +beginning of the output. Eg: 'OK: Ram Total:...' will become 'Ram Total:...' =item B<--output-xml> -Display output in XML format. +Return the output in XML format (to send to an XML API). =item B<--output-json> -Display output in JSON format. +Return the output in JSON format (to send to a JSON API). =item B<--output-openmetrics> -Display metrics in OpenMetrics format. +Return the output in OpenMetrics format (to send to a tool expecting this +format). =item B<--output-file> -Write output in file (can be used with json and xml options) +Write output in file (can be combined with json, xml and openmetrics options). +E.g.: --output-file=/tmp/output.txt will write the output in /tmp/output.txt. =item B<--disco-format> -Display discovery arguments (if the mode manages it). +Applies only to modes beginning with 'list-'. +Returns the list of available macros to configure a service discovery rule +(formatted in XML). =item B<--disco-show> -Display discovery values (if the mode manages it). +Applies only to modes beginning with 'list-'. +Returns the list of discovered objects (formatted in XML) for service discovery. =item B<--float-precision> -Set the float precision for thresholds (default: 8). +Define the float precision for thresholds (default: 8). =item B<--source-encoding> -Set encoding of monitoring sources (in some cases. Default: 'UTF-8'). +Define the character encoding of the response sent by the monitored resource +Default: 'UTF-8'. =head1 DESCRIPTION diff --git a/src/centreon/plugins/script.pm b/src/centreon/plugins/script.pm index a81711581..faee006e9 100644 --- a/src/centreon/plugins/script.pm +++ b/src/centreon/plugins/script.pm @@ -455,33 +455,34 @@ List all available plugins. =item B<--version> -Print global version. +Return the version of the plugin. =item B<--help> -Print a brief help message and exits. +Return the help message for the plugin and exit. =item B<--ignore-warn-msg> -Perl warn messages are ignored (not displayed). +Ignore Perl warning messages (they will not be displayed). =item B<--runas> -Run the script as a different user (prefer to use directly the good user). +Run the script as a different user. =item B<--global-timeout> -Set script timeout. +Define the script's timeout. =item B<--environment> -Set environment variables for the script (set them in the execution environment +Define environment variables for the script (set them in the execution environment before running it for better performance). =item B<--convert-args> -Change strings of arguments. Useful to use '!' in nrpe protocol. -Example: --convert-args='##,\x21' +Replace a pattern in the provided arguments. Useful to bypass forbidden characters. +E.g.: when a password transmitted via the NRPE protocol contains '!' (which is +interpreted as a separator), you can send '##' instead of the '!' and the plugin will replace '##' with '!', using the --convert-args='##,\x21' option. =back diff --git a/src/centreon/plugins/script_custom.pm b/src/centreon/plugins/script_custom.pm index 60221f453..177f6aadd 100644 --- a/src/centreon/plugins/script_custom.pm +++ b/src/centreon/plugins/script_custom.pm @@ -287,7 +287,7 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display the plugin's version. +Return the version of the plugin. =item B<--custommode> diff --git a/src/centreon/plugins/script_simple.pm b/src/centreon/plugins/script_simple.pm index e66b4743b..65cf79c6a 100644 --- a/src/centreon/plugins/script_simple.pm +++ b/src/centreon/plugins/script_simple.pm @@ -218,7 +218,7 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display the plugin's version. +Return the version of the plugin. =item B<--pass-manager> diff --git a/src/centreon/plugins/script_snmp.pm b/src/centreon/plugins/script_snmp.pm index c8c9c1af3..45bb4ef80 100644 --- a/src/centreon/plugins/script_snmp.pm +++ b/src/centreon/plugins/script_snmp.pm @@ -226,7 +226,7 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display the plugin's version. +Return the version of the plugin. =item B<--pass-manager> diff --git a/src/centreon/plugins/script_sql.pm b/src/centreon/plugins/script_sql.pm index d7b786ee6..415989eff 100644 --- a/src/centreon/plugins/script_sql.pm +++ b/src/centreon/plugins/script_sql.pm @@ -286,19 +286,20 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display the plugin's version. +Return the version of the plugin. =item B<--sqlmode> -Choose a sql mode (Default: "dbi"). +This plugin offers several ways to query the database (default: dbi). +See --list-sqlmode. =item B<--list-sqlmode> -List available sql modes. +List all available sql modes. =item B<--multiple> -Multiple database connections (required by some specific modes). +Enable connecting to multiple databases (required by some specific modes such as replication). =item B<--pass-manager> diff --git a/src/centreon/plugins/script_wsman.pm b/src/centreon/plugins/script_wsman.pm index 2ad465462..5293d22ea 100644 --- a/src/centreon/plugins/script_wsman.pm +++ b/src/centreon/plugins/script_wsman.pm @@ -222,7 +222,7 @@ Check minimal version of mode. If not, unknown error. =item B<--version> -Display the plugin's version. +Return the version of the plugin. =item B<--pass-manager> diff --git a/src/centreon/plugins/snmp.pm b/src/centreon/plugins/snmp.pm index 55aad3490..40757165d 100644 --- a/src/centreon/plugins/snmp.pm +++ b/src/centreon/plugins/snmp.pm @@ -1106,27 +1106,29 @@ snmp class =item B<--hostname> -Hostname to query (required). +Name or address of the host to monitor (mandatory). =item B<--snmp-community> -Read community (defaults to public). +SNMP community (default value: public). It is recommended to use a read-only +community. =item B<--snmp-version> -Version: 1 for SNMP v1 (default), 2 for SNMP v2c, 3 for SNMP v3. +Version of the SNMP protocol. 1 for SNMP v1 (default), 2 for SNMP v2c, 3 for SNMP v3. =item B<--snmp-port> -Port (default: 161). +UDP port to send the SNMP request to (default: 161). =item B<--snmp-timeout> -Timeout in secondes (default: 1) before retries. +Time to wait before sending the request again if no reply has been received, +in seconds (default: 1). See also --snmp-retries. =item B<--snmp-retries> -Set the number of retries (default: 5) before failure. +Maximum number of retries (default: 5). =item B<--maxrepetitions> @@ -1138,11 +1140,13 @@ How many oid values per SNMP request (default: 50) (for get_leef method. Be caut =item B<--snmp-autoreduce> -Auto reduce SNMP request size in case of SNMP errors (By default, the divisor is 2). +Progressively reduce the number requested OIDs in bulk mode. Use it in case of +SNMP errors (By default, the number is divided by 2). =item B<--snmp-force-getnext> -Use snmp getnext function (even in snmp v2c and v3). +Use snmp getnext function in snmp v2c and v3. This will request one OID at a +time. =item B<--snmp-cache-file> @@ -1150,69 +1154,77 @@ Use SNMP cache file. =item B<--snmp-username> -Security name (only for SNMP v3). +SNMP v3 only: +User name (securityName). =item B<--authpassphrase> -Authentication protocol pass phrase. +SNMP v3 only: +Pass phrase hashed using the authentication protocol defined in the +--authprotocol option. =item B<--authprotocol> +SNMP v3 only: Authentication protocol: MD5|SHA. Since net-snmp 5.9.1: SHA224|SHA256|SHA384|SHA512. =item B<--privpassphrase> -Privacy protocol pass phrase +SNMP v3 only: +Privacy pass phrase (privPassword) to encrypt messages using the protocol +defined in the --privprotocol option. =item B<--privprotocol> -Privacy protocol: DES|AES. Since net-snmp 5.9.1: AES192|AES192C|AES256|AES256C. +SNMP v3 only: +Privacy protocol (privProtocol) used to encrypt messages. +Supported protocols are: DES|AES and since net-snmp 5.9.1: AES192|AES192C|AES256|AES256C. =item B<--contextname> -Context name +SNMP v3 only: +Context name (contextName), if relevant for the monitored host. =item B<--contextengineid> -Context engine ID +SNMP v3 only: +Context engine ID (contextEngineID), if relevant for the monitored host, given +as a hexadecimal string. =item B<--securityengineid> -Security engine ID +SNMP v3 only: +Security engine ID, given as a hexadecimal string. =item B<--snmp-errors-exit> -Exit code for SNMP Errors (default: unknown) +Expected status in case of SNMP error or timeout. +Possible values are warning, critical and unknown (default). =item B<--snmp-tls-transport> -TLS Transport communication used (can be: 'dtlsudp', 'tlstcp'). +Transport protocol for TLS communication (can be: 'dtlsudp', 'tlstcp'). =item B<--snmp-tls-our-identity> -Our X.509 identity to use, which should either be a fingerprint or the -filename that holds the certificate. +X.509 certificate to identify ourselves. Can be the path to the certificate file +or its contents. =item B<--snmp-tls-their-identity> -The remote server's identity to connect to, specified as either a -fingerprint or a file name. Either this must be specified, or the -hostname below along with a trust anchor. +X.509 certificate to identify the remote host. Can be the path to the +certificate file or its contents. This option is unnecessary if the certificate +is already trusted by your system. =item B<--snmp-tls-their-hostname> -The remote server's hostname that is expected. If their certificate -was signed by a CA then their hostname presented in the certificate -must match this value or the connection fails to be established (to -avoid man-in-the-middle attacks). +Common Name (CN) expected in the certificate sent by the host if it differs from +the value of the --hostname parameter. =item B<--snmp-tls-trust-cert> -A trusted certificate to use as trust anchor (like a CA certificate) -for verifying a remote server's certificate. If a CA certificate is -used to validate a certificate then the TheirHostname parameter must -also be specified to ensure their presented hostname in the certificate -matches. +A trusted CA certificate used to verify a remote host's certificate. +If you use this option, you must also define --snmp-tls-their-hostname. =back diff --git a/src/centreon/plugins/ssh.pm b/src/centreon/plugins/ssh.pm index f89f9a174..6e56f43ae 100644 --- a/src/centreon/plugins/ssh.pm +++ b/src/centreon/plugins/ssh.pm @@ -108,8 +108,8 @@ SSH abstraction layer for sscli, plink and libssh backends =item B<--ssh-backend> -Set the backend used (Default: 'sshcli') -Can be: sshcli, plink, libssh. +Define the backend you want to use. +It can be: sshcli (default), plink and libssh. =item B<--ssh-username> From 765eadd57f8beebced2290a6983317cf7d66e07a Mon Sep 17 00:00:00 2001 From: Lucie Dubrunfaut <123162035+lucie-dubrunfaut@users.noreply.github.com> Date: Wed, 7 Jun 2023 10:03:50 +0200 Subject: [PATCH 444/447] (plugin) network::cambium::cnpilot::snmp - add list-interfaces mode --- .../deb.json | 5 +++++ .../pkg.json | 14 ++++++++++++++ .../rpm.json | 5 +++++ src/network/cambium/cnpilot/snmp/plugin.pm | 1 + 4 files changed, 25 insertions(+) create mode 100644 packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/deb.json create mode 100644 packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/pkg.json create mode 100644 packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/rpm.json diff --git a/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/deb.json b/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/deb.json new file mode 100644 index 000000000..663aaaceb --- /dev/null +++ b/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libsnmp-perl" + ] +} \ No newline at end of file diff --git a/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/pkg.json b/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/pkg.json new file mode 100644 index 000000000..246574411 --- /dev/null +++ b/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/pkg.json @@ -0,0 +1,14 @@ +{ + "pkg_name": "centreon-plugin-Network-Cambium-Cnpilot-Snmp", + "pkg_summary": "Centreon Plugin", + "plugin_name": "centreon_cambium_cnpilot.pl", + "files": [ + "centreon/plugins/script_snmp.pm", + "centreon/plugins/snmp.pm", + "snmp_standard/mode/listinterfaces.pm", + "snmp_standard/mode/interfaces.pm", + "snmp_standard/mode/uptime.pm", + "snmp_standard/mode/resources/", + "network/cambium/cnpilot/snmp/" + ] +} \ No newline at end of file diff --git a/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/rpm.json b/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/rpm.json new file mode 100644 index 000000000..418a331fc --- /dev/null +++ b/packaging/centreon-plugin-Network-Cambium-Cnpilot-Snmp/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(SNMP)" + ] +} \ No newline at end of file diff --git a/src/network/cambium/cnpilot/snmp/plugin.pm b/src/network/cambium/cnpilot/snmp/plugin.pm index 326b2f56f..de6cf1264 100644 --- a/src/network/cambium/cnpilot/snmp/plugin.pm +++ b/src/network/cambium/cnpilot/snmp/plugin.pm @@ -33,6 +33,7 @@ sub new { 'connection-status' => 'network::cambium::cnpilot::snmp::mode::connectionstatus', 'cpu' => 'network::cambium::cnpilot::snmp::mode::cpu', 'interfaces' => 'network::cambium::cnpilot::snmp::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'list-radios' => 'network::cambium::cnpilot::snmp::mode::listradios', 'memory' => 'network::cambium::cnpilot::snmp::mode::memory', 'radios' => 'network::cambium::cnpilot::snmp::mode::radios' From aaa667e087c884d6a4818e158e3f7da957787fce Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 7 Jun 2023 10:04:05 +0200 Subject: [PATCH 445/447] =?UTF-8?q?(plugin)=20apps::wallix::bastion::snmp?= =?UTF-8?q?=20-=20mode=20license=20add=20--filter-cate=E2=80=A6=20(#4447)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apps/wallix/bastion/snmp/mode/license.pm | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/apps/wallix/bastion/snmp/mode/license.pm b/src/apps/wallix/bastion/snmp/mode/license.pm index d483251fe..4b370259e 100644 --- a/src/apps/wallix/bastion/snmp/mode/license.pm +++ b/src/apps/wallix/bastion/snmp/mode/license.pm @@ -191,7 +191,8 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - 'unit:s' => { name => 'unit', default => 's' } + 'filter-category:s' => { name => 'filter_category' }, + 'unit:s' => { name => 'unit', default => 's' } }); return $self; @@ -209,6 +210,9 @@ sub check_options { sub add_license { my ($self, %options) = @_; + return if (defined($self->{option_results}->{filter_category}) && $self->{option_results}->{filter_category} ne '' && + $options{name} !~ /$self->{option_results}->{filter_category}/); + $self->{licenses}->{ $options{name} } = { name => $options{name}, used => $options{used} @@ -300,6 +304,15 @@ Check license. =over 8 +=item B<--filter-category> + +Filter licenses by category ('primary', 'secondary', 'resource'). + +=item B<--unit> + +Select the unit for the expired license threshold. May be 's' for seconds, 'm' for minutes, +'h' for hours, 'd' for days, 'w' for weeks. Default is seconds. + =item B<--warning-status> Set warning threshold for status. @@ -310,11 +323,6 @@ You can use the following variables: %{status} Set critical threshold for status (Default: '%{status} eq "expired"'). You can use the following variables: %{status} -=item B<--unit> - -Select the unit for expires threshold. May be 's' for seconds, 'm' for minutes, -'h' for hours, 'd' for days, 'w' for weeks. Default is seconds. - =item B<--warning-*> B<--critical-*> Thresholds. From 9f31f702ab7fb76f3db6565b88cdb9cbe3c8fb21 Mon Sep 17 00:00:00 2001 From: sdepassio <114986849+sdepassio@users.noreply.github.com> Date: Wed, 7 Jun 2023 12:10:04 +0200 Subject: [PATCH 446/447] (plugin) cloud::aws::cloudtrail - new (#4449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * plugin aws cloudtrail * update * update + add tests * update workflow * fix * update --- .github/workflows/tests-functional.yml | 61 ++++++++ .../deb.json | 5 + .../pkg.json | 10 ++ .../rpm.json | 5 + .../aws/cloudtrail/mode/checktrailstatus.pm | 84 +++++++++++ src/cloud/aws/cloudtrail/mode/countevents.pm | 126 +++++++++++++++++ src/cloud/aws/cloudtrail/plugin.pm | 51 +++++++ src/cloud/aws/custom/awscli.pm | 74 ++++++++++ src/cloud/aws/custom/paws.pm | 65 ++++++++- .../cloud/aws/cloudtrail/checktrailstatus.sh | 34 +++++ .../cloud/aws/cloudtrail/countevents.sh | 106 ++++++++++++++ .../mockoon/cloud-aws-cloudtrail.json | 130 ++++++++++++++++++ 12 files changed, 750 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/tests-functional.yml create mode 100644 packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/deb.json create mode 100644 packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/pkg.json create mode 100644 packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/rpm.json create mode 100644 src/cloud/aws/cloudtrail/mode/checktrailstatus.pm create mode 100644 src/cloud/aws/cloudtrail/mode/countevents.pm create mode 100644 src/cloud/aws/cloudtrail/plugin.pm create mode 100644 tests/functional/cloud/aws/cloudtrail/checktrailstatus.sh create mode 100644 tests/functional/cloud/aws/cloudtrail/countevents.sh create mode 100644 tests/resources/mockoon/cloud-aws-cloudtrail.json diff --git a/.github/workflows/tests-functional.yml b/.github/workflows/tests-functional.yml new file mode 100644 index 000000000..31f20ccf5 --- /dev/null +++ b/.github/workflows/tests-functional.yml @@ -0,0 +1,61 @@ +name: Run mock API server +on: + workflow_dispatch: + push: + branches: + - MON-** + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js + uses: actions/setup-node@v2 + with: + node-version: "14.x" + - name: Install Mockoon CLI + run: npm install -D @mockoon/cli + - name: Install perl dependencies + uses: perl-actions/install-with-cpm@stable + with: + install: | + DateTime + Digest::MD5 + Encode + HTTP::ProxyPAC + IO::Socket::SSL + JSON::XS + LWP::Protocol::https + LWP::UserAgent + MIME::Base64 + Paws + POSIX + Storable + URI + URI::Encode + - name: Run Mockoon CLI + run: npx mockoon-cli start --data tests/resources/mockoon/cloud-aws-cloudtrail.json --port 3000 + - name: Run plugin + run: | + sudo chmod -R +x tests/functional/ + sudo mkdir -p /var/lib/centreon/centplugins/ + sudo chmod 777 /var/lib/centreon/centplugins/ + TESTS="$(tests/functional/cloud/aws/cloudtrail/checktrailstatus.sh)" + echo "tests=$(echo $TESTS)" >> $GITHUB_OUTPUT + if [[ $TESTS = "OK:"* ]]; then + echo "OK" + else + echo $TESTS + exit 1 + fi + TESTS="$(tests/functional/cloud/aws/cloudtrail/countevents.sh)" + echo "tests=$(echo $TESTS)" >> $GITHUB_OUTPUT + if [[ $TESTS = "OK:"* ]]; then + echo "OK" + else + echo $TESTS + exit 1 + fi + shell: bash \ No newline at end of file diff --git a/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/deb.json b/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/deb.json new file mode 100644 index 000000000..bc17ef2ad --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/deb.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "libdatetime-perl" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/pkg.json b/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/pkg.json new file mode 100644 index 000000000..da2493eb9 --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/pkg.json @@ -0,0 +1,10 @@ +{ + "pkg_name": "centreon-plugin-Cloud-Aws-Cloudtrail-Api", + "pkg_summary": "Centreon Plugin to monitor Amazon AWS using Cloudtrail API", + "plugin_name": "centreon_aws_cloudtrail_api.pl", + "files": [ + "centreon/plugins/script_custom.pm", + "cloud/aws/custom/", + "cloud/aws/cloudtrail/" + ] +} diff --git a/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/rpm.json b/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/rpm.json new file mode 100644 index 000000000..bc30a2c0d --- /dev/null +++ b/packaging/centreon-plugin-Cloud-Aws-Cloudtrail-Api/rpm.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "perl(DateTime)" + ] +} diff --git a/src/cloud/aws/cloudtrail/mode/checktrailstatus.pm b/src/cloud/aws/cloudtrail/mode/checktrailstatus.pm new file mode 100644 index 000000000..b360db747 --- /dev/null +++ b/src/cloud/aws/cloudtrail/mode/checktrailstatus.pm @@ -0,0 +1,84 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::cloudtrail::mode::checktrailstatus; + +use strict; +use warnings; + +use base qw(centreon::plugins::mode); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'trail-name:s' => { name => 'trail_name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!length($self->{option_results}->{trail_name})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --trail-name option."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my $status = $options{custom}->cloudtrail_trail_status( + trail_name => $self->{option_results}->{trail_name} + ); + + $self->{output}->output_add(severity => $status->{IsLogging} ? "ok" : "critical", + short_msg => sprintf("Trail is logging: %s", $status->{IsLogging})); + $self->{output}->perfdata_add(label => "trail_is_logging", unit => '', + value => sprintf("%s", $status->{IsLogging} ), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + + +1; + +=head1 MODE + +Check cloudtrail trail status. + +=over 8 + +=item B<--trail-name> + +Filter by trail name. + +=back + +=cut \ No newline at end of file diff --git a/src/cloud/aws/cloudtrail/mode/countevents.pm b/src/cloud/aws/cloudtrail/mode/countevents.pm new file mode 100644 index 000000000..bb9891348 --- /dev/null +++ b/src/cloud/aws/cloudtrail/mode/countevents.pm @@ -0,0 +1,126 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::cloudtrail::mode::countevents; + +use strict; +use warnings; + +use base qw(centreon::plugins::mode); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'event-type:s' => { name => 'event_type' }, + 'error-message:s' => { name => 'error_message' }, + 'delta:s' => { name => 'delta' }, + 'warning-count:s' => { name => 'warning_count' }, + 'critical-count:s' => { name => 'critical_count' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning-count', value => $self->{option_results}->{warning_count})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-count threshold '" . $self->{option_results}->{warning_count} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-count', value => $self->{option_results}->{critical_count})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-count threshold '" . $self->{option_results}->{critical_count} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + $self->{events} = $options{custom}->cloudtrail_events( + event_type => $self->{option_results}->{event_type}, + error_message => $self->{option_results}->{error_message}, + delta => $self->{option_results}->{delta} + ); + + my $count; + if (length($self->{option_results}->{event_type}) || length($self->{option_results}->{error_message})) { + $count = 0; + foreach my $event (@{$self->{events}}) { + if ((defined($self->{option_results}->{event_type}) && length($self->{option_results}->{event_type}) && ($event->{eventType} eq $self->{option_results}->{event_type})) + || (defined($self->{option_results}->{error_message}) && length($self->{option_results}->{error_message}) && ($event->{errorMessage} =~ $self->{option_results}->{error_message}))) { + $count++; + } + } + } else { + $count = scalar @{$self->{events}}; + } + + my $exit = $self->{perfdata}->threshold_check(value => $count, threshold => [ { label => 'critical-count', exit_litteral => 'critical' }, { label => 'warning-count', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Number of events: %.2f", $count)); + $self->{output}->perfdata_add(label => "events_count", unit => '', + value => sprintf("%.2f", $count), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check cloudtrail events. + +=over 8 + +=item B<--event-type> + +Filter by event type. + +=item B<--error-message> + +Filter on an error message pattern + +=item B<--delta> + +Time depth for search (minutes). + +=item B<--warning-count> + +Set warning threshold for the number of events. + +=item B<--critical-count> + +Set critical threshold for the number of events. + +=back + +=cut diff --git a/src/cloud/aws/cloudtrail/plugin.pm b/src/cloud/aws/cloudtrail/plugin.pm new file mode 100644 index 000000000..4274dd1e3 --- /dev/null +++ b/src/cloud/aws/cloudtrail/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2023 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package cloud::aws::cloudtrail::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'checktrailstatus' => 'cloud::aws::cloudtrail::mode::checktrailstatus', + 'countevents' => 'cloud::aws::cloudtrail::mode::countevents' + ); + + $self->{custom_modes}{paws} = 'cloud::aws::custom::paws'; + $self->{custom_modes}{awscli} = 'cloud::aws::custom::awscli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Amazon CloudTrail. + +=cut diff --git a/src/cloud/aws/custom/awscli.pm b/src/cloud/aws/custom/awscli.pm index 385938762..2843e5d27 100644 --- a/src/cloud/aws/custom/awscli.pm +++ b/src/cloud/aws/custom/awscli.pm @@ -976,6 +976,80 @@ sub directconnect_describe_virtual_interfaces { return $results; } +sub cloudtrail_events_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "lookup-events --region $self->{option_results}->{region} --output json"; + if (defined($options{delta})) { + my $endtime = time(); + my $starttime = $endtime - ($options{delta} * 60); + $cmd_options .= " --start-time $starttime"; + $cmd_options .= " --end-time $endtime"; + } + $cmd_options .= " --starting-token $options{next_token}" if (length($options{next_token})); + $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (length($self->{endpoint_url})); + $cmd_options .= " --no-verify-ssl 2>/dev/null" if (length($self->{option_results}->{skip_ssl_check})); + + return $cmd_options; +} + +sub cloudtrail_events { + my ($self, %options) = @_; + + my $cmd_options = $self->cloudtrail_events_set_cmd(%options); + + my $events_results = []; + eval { + while (my $list_events = $self->execute(cmd_options => $cmd_options)) { + foreach (@{$list_events->{Events}}) { + my $event = JSON::XS->new->utf8->decode($_->{CloudTrailEvent}); + push @{$events_results}, { + eventID => $event->{eventID}, + eventType => $event->{eventType}, + errorMessage => $event->{errorMessage} + }; + } + + last if (!defined($list_events->{NextToken})); + $options{next_token} = $list_events->{NextToken}; + } + }; + + return $events_results; +} + +sub cloudtrail_trail_status_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "get-trail-status --region $self->{option_results}->{region} --output json"; + $cmd_options .= " --name $options{trail_name}"; + $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (length($self->{endpoint_url})); + $cmd_options .= " --no-verify-ssl 2>/dev/null" if (length($self->{option_results}->{skip_ssl_check})); + + return $cmd_options; +} + +sub cloudtrail_trail_status { + my ($self, %options) = @_; + + my $cmd_options = $self->cloudtrail_trail_status_set_cmd(%options); + + my $trail_status; + eval { + $trail_status = $self->execute(cmd_options => $cmd_options); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $trail_status; +} + 1; __END__ diff --git a/src/cloud/aws/custom/paws.pm b/src/cloud/aws/custom/paws.pm index dc6b433c6..e4cca26be 100644 --- a/src/cloud/aws/custom/paws.pm +++ b/src/cloud/aws/custom/paws.pm @@ -50,7 +50,8 @@ sub new { 'period:s' => { name => 'period' }, 'statistic:s@' => { name => 'statistic' }, 'zeroed' => { name => 'zeroed' }, - 'proxyurl:s' => { name => 'proxyurl' } + 'proxyurl:s' => { name => 'proxyurl' }, + 'endpoint:s' => { name => 'endpoint' } }); } $options{options}->add_help(package => __PACKAGE__, sections => 'PAWS OPTIONS', once => 1); @@ -839,6 +840,68 @@ sub directconnect_describe_virtual_interfaces { return $results; } +sub cloudtrail_events { + my ($self, %options) = @_; + + my $events_results = []; + eval { + my $ct; + if (defined($self->{option_results}->{endpoint}) && length $self->{option_results}->{endpoint}) { + $ct = $self->{paws}->service('CloudTrail', region => $self->{option_results}->{region} , endpoint => $self->{option_results}->{endpoint}); + } else { + $ct = $self->{paws}->service('CloudTrail', region => $self->{option_results}->{region}); + } + my %ct_options = (); + if (defined($options{delta})) { + $ct_options{EndTime} = time(); + $ct_options{StartTime} = $ct_options{EndTime} - ($options{delta} * 60); + } + + while (my $list_events = $ct->LookupEvents(%ct_options)) { + foreach (@{$list_events->{Events}}) { + my $event = JSON::XS->new->utf8->decode($_->{CloudTrailEvent}); + push @{$events_results}, { + eventID => $event->{eventID}, + eventType => $event->{eventType}, + errorMessage => $event->{errorMessage} + }; + } + + last if (!defined($list_events->{NextToken})); + $ct_options{NextToken} = $list_events->{NextToken}; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $events_results; +} + +sub cloudtrail_trail_status { + my ($self, %options) = @_; + + my $trail_status; + eval { + my $ct; + if (defined($self->{option_results}->{endpoint}) && length $self->{option_results}->{endpoint}) { + $ct = $self->{paws}->service('CloudTrail', region => $self->{option_results}->{region} , endpoint => $self->{option_results}->{endpoint}); + } else { + $ct = $self->{paws}->service('CloudTrail', region => $self->{option_results}->{region}); + } + my %ct_options = (); + $ct_options{Name} = $options{trail_name}; + $trail_status = $ct->GetTrailStatus(%ct_options); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $trail_status; +} + 1; __END__ diff --git a/tests/functional/cloud/aws/cloudtrail/checktrailstatus.sh b/tests/functional/cloud/aws/cloudtrail/checktrailstatus.sh new file mode 100644 index 000000000..252d7c44c --- /dev/null +++ b/tests/functional/cloud/aws/cloudtrail/checktrailstatus.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +current_dir="$( cd "$(dirname "$0")/../../../../.." >/dev/null 2>&1 || exit ; pwd -P )" +cmd="perl $current_dir/src/centreon_plugins.pl --plugin=cloud::aws::cloudtrail::plugin --custommode=paws --region=eu-west --aws-secret-key=secret --aws-access-key=key" + +nb_tests=0 +nb_tests_ok=0 + +test_status_ok=$($cmd --mode=checktrailstatus --endpoint=http://localhost:3000/cloudtrail/gettrailstatus/true --trail-name=TrailName) +((nb_tests++)) +if [[ $test_status_ok = "OK: Trail is logging: 1 | 'trail_is_logging'=1;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_status_ok ko" + echo $test_status_ok +fi + +test_status_critical=$($cmd --mode=checktrailstatus --endpoint=http://localhost:3000/cloudtrail/gettrailstatus/false --trail-name=TrailName) +((nb_tests++)) +if [[ $test_status_critical = "CRITICAL: Trail is logging: 0 | 'trail_is_logging'=0;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_status_critical ko" + echo $test_status_critical +fi + +if [[ $nb_tests_ok = $nb_tests ]] +then + echo "OK: "$nb_tests_ok"/"$nb_tests" tests OK" +else + echo "NOK: "$nb_tests_ok"/"$nb_tests" tests OK" +fi diff --git a/tests/functional/cloud/aws/cloudtrail/countevents.sh b/tests/functional/cloud/aws/cloudtrail/countevents.sh new file mode 100644 index 000000000..7656ba872 --- /dev/null +++ b/tests/functional/cloud/aws/cloudtrail/countevents.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +current_dir="$( cd "$(dirname "$0")/../../../../.." >/dev/null 2>&1 || exit ; pwd -P )" +cmd="perl $current_dir/src/centreon_plugins.pl --plugin=cloud::aws::cloudtrail::plugin --custommode=paws --region=eu-west --aws-secret-key=secret --aws-access-key=key" + +nb_tests=0 +nb_tests_ok=0 + +endpoint_url="http://localhost:3000/cloudtrail/events/AwsApiCall/4/AwsServiceEvent/2/AwsConsoleAction/1/AwsConsoleSignIn/3/NextToken/t" + +test_ok=$($cmd --mode=countevents --endpoint=$endpoint_url) +((nb_tests++)) +if [[ $test_ok = "OK: Number of events: 10.00 | 'events_count'=10.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_ok ko" + echo $test_ok +fi + +test_oknexttoken=$($cmd --mode=countevents --endpoint=$endpoint_url"rue") +((nb_tests++)) +if [[ $test_oknexttoken = "OK: Number of events: 20.00 | 'events_count'=20.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "$test_oknexttoken ko" + echo $test_oknexttoken +fi + +test_okeventtype=$($cmd --mode=countevents --endpoint=$endpoint_url --event-type=AwsApiCall) +((nb_tests++)) +if [[ $test_okeventtype = "OK: Number of events: 4.00 | 'events_count'=4.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_okeventtype ko" + echo $test_okeventtype +fi + +test_okeventtypenexttoken=$($cmd --mode=countevents --endpoint=$endpoint_url"rue" --event-type=AwsServiceEvent) +((nb_tests++)) +if [[ $test_okeventtypenexttoken = "OK: Number of events: 4.00 | 'events_count'=4.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_okeventtypenexttoken ko" + echo $test_okeventtypenexttoken +fi + +test_okdelta=$($cmd --mode=countevents --endpoint=$endpoint_url --event-type=AwsApiCall --delta=10) +((nb_tests++)) +if [[ $test_okdelta = "OK: Number of events: 4.00 | 'events_count'=4.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_okdelta ko" + echo $test_okdelta +fi + +test_okerrormessage=$($cmd --mode=countevents --endpoint=$endpoint_url --error-message='Login error') +((nb_tests++)) +if [[ $test_okerrormessage = "OK: Number of events: 3.00 | 'events_count'=3.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_okerrormessage ko" + echo $test_okerrormessage +fi + +test_okerrormessagepartial=$($cmd --mode=countevents --endpoint=$endpoint_url --error-message='.*error') +((nb_tests++)) +if [[ $test_okerrormessagepartial = "OK: Number of events: 4.00 | 'events_count'=4.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_okerrormessagepartial ko" + echo $test_okerrormessagepartial +fi + +test_warning=$($cmd --mode=countevents --endpoint=$endpoint_url --warning-count=3) +((nb_tests++)) +if [[ $test_warning = "WARNING: Number of events: 10.00 | 'events_count'=10.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_warning ko" + echo $test_warning +fi + +test_critical=$($cmd --mode=countevents --endpoint=$endpoint_url --critical-count=5) +((nb_tests++)) +if [[ $test_critical = "CRITICAL: Number of events: 10.00 | 'events_count'=10.00;;;0;" ]] +then + ((nb_tests_ok++)) +else + echo "test_critical ko" + echo $test_critical +fi + +if [[ $nb_tests_ok = $nb_tests ]] +then + echo "OK: "$nb_tests_ok"/"$nb_tests" tests OK" +else + echo "NOK: "$nb_tests_ok"/"$nb_tests" tests OK" +fi diff --git a/tests/resources/mockoon/cloud-aws-cloudtrail.json b/tests/resources/mockoon/cloud-aws-cloudtrail.json new file mode 100644 index 000000000..f25264798 --- /dev/null +++ b/tests/resources/mockoon/cloud-aws-cloudtrail.json @@ -0,0 +1,130 @@ +{ + "uuid": "e59ad81e-2050-480d-bbae-0e71c607c927", + "lastMigration": 27, + "name": "Aws cloudtrail", + "endpointPrefix": "", + "latency": 0, + "port": 3000, + "hostname": "", + "folders": [], + "routes": [ + { + "uuid": "b5e25f3a-a8e3-4128-9e45-f2654c5a599d", + "type": "http", + "documentation": "", + "method": "post", + "endpoint": "cloudtrail/gettrailstatus/:islogging", + "responses": [ + { + "uuid": "76483999-2022-4610-8e8c-9c0bd535e4c5", + "body": "{\r\n \"IsLogging\": {{ urlParam 'islogging' 'true' }},\r\n \"LatestCloudWatchLogsDeliveryError\": \"error\",\r\n \"LatestCloudWatchLogsDeliveryTime\": 1683298944.125,\r\n \"LatestDeliveryAttemptSucceeded\": \"2023-05-05T15:02:24Z\",\r\n \"LatestDeliveryAttemptTime\": \"2023-05-05T15:02:24Z\",\r\n \"LatestDeliveryError\": \"error\",\r\n \"LatestDeliveryTime\": 1683298944.125,\r\n \"LatestDigestDeliveryError\": \"error\",\r\n \"LatestDigestDeliveryTime\": 1683298944.125,\r\n \"LatestNotificationAttemptSucceeded\": \"2023-05-05T15:02:24Z\",\r\n \"LatestNotificationAttemptTime\": \"2023-05-05T15:02:24Z\",\r\n \"LatestNotificationError\": \"error\",\r\n \"LatestNotificationTime\": 1683298944.125,\r\n \"StartLoggingTime\": 1683298944.125,\r\n \"StopLoggingTime\": 1683298477.918,\r\n \"TimeLoggingStarted\": \"2023-05-05T15:02:24Z\",\r\n \"TimeLoggingStopped\": \"2023-05-05T14:54:37Z\"\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true + } + ], + "enabled": true, + "responseMode": null + }, + { + "uuid": "77f82f1c-b06e-478a-8366-ab325830f00e", + "type": "http", + "documentation": "", + "method": "post", + "endpoint": "cloudtrail/events/AwsApiCall/:AwsApiCall/AwsServiceEvent/:AwsServiceEvent/AwsConsoleAction/:AwsConsoleAction/AwsConsoleSignIn/:AwsConsoleSignIn/NextToken/:NextToken", + "responses": [ + { + "uuid": "7dd41177-8d63-458a-abcc-b3af3ea8c9cd", + "body": "{\r\n\t\"Events\": [\r\n\t\t{{#each (dataRaw 'Events')}}\r\n\t\t {{#if (gt @index 0)}}\r\n\t\t ,\r\n\t\t {{/if}}\r\n \t\t{\r\n \t\t\t\"AccessKeyId\": \"{{AccessKeyId}}\",\r\n \t\t\t\"CloudTrailEvent\": \"{\\\"awsRegion\\\": \\\"eu-west-1\\\", {{#if Error}}\\\"errorCode\\\": \\\"{{ErrorCode}}\\\", \\\"errorMessage\\\": \\\"{{ErrorMessage}}\\\",{{/if}} \\\"eventCategory\\\": \\\"Management\\\", \\\"eventID\\\": \\\"{{EventId}}\\\", \\\"eventName\\\": \\\"{{EventName}}\\\", \\\"eventSource\\\": \\\"{{EventSource}}\\\", \\\"eventTime\\\": \\\"{{EventTime}}\\\", \\\"eventType\\\": \\\"{{EventType}}\\\", \\\"eventVersion\\\": \\\"1.08\\\", \\\"managementEvent\\\": true, \\\"readOnly\\\": true, \\\"recipientAccountId\\\": \\\"{{AccountId}}\\\", \\\"requestID\\\": \\\"{{ faker 'datatype.uuid' }}\\\", \\\"requestParameters\\\": null, \\\"responseElements\\\": null, \\\"sourceIPAddress\\\": \\\"{{ faker 'internet.ip' }}\\\", \\\"tlsDetails\\\": {\\\"cipherSuite\\\": \\\"ECDHE-RSA-AES128-GCM-SHA256\\\", \\\"clientProvidedHostHeader\\\": \\\"cloudtrail.eu-west-1.amazonaws.com\\\", \\\"tlsVersion\\\": \\\"TLSv1.2\\\"}, \\\"userAgent\\\": \\\"aws-cli/2.11.0 Python/3.11.2 Darwin/22.2.0 source/x86_64 prompt/off command/cloudtrail.lookup-events\\\", \\\"userIdentity\\\": {\\\"accessKeyId\\\": \\\"{{AccessKeyId}}\\\", \\\"accountId\\\": \\\"{{AccountId}}\\\", \\\"arn\\\": \\\"arn:aws:sts::{{AccountId}}:assumed-role/{{UserRole}}/{{UserName}}\\\", \\\"principalId\\\": \\\"{{PrincipalId}}:{{UserName}}\\\", \\\"sessionContext\\\": {\\\"attributes\\\": {\\\"creationDate\\\": \\\"{{ faker 'date.past' EventTime }}\\\", \\\"mfaAuthenticated\\\": \\\"false\\\"}, \\\"sessionIssuer\\\": {\\\"accountId\\\": \\\"{{AccountId}}\\\", \\\"arn\\\": \\\"arn:aws:iam::{{AccountId}}:role/{{UserRole}}\\\", \\\"principalId\\\": \\\"{{PrincipalId}}\\\", \\\"type\\\": \\\"Role\\\", \\\"userName\\\": \\\"{{UserRole}}\\\"}, \\\"webIdFederationData\\\": {}}, \\\"type\\\": \\\"{{ faker 'name.jobArea' }}\\\"}}\",\r\n \t\t\t\"EventId\": \"{{EventId}}\",\r\n \t\t\t\"EventName\": \"{{EventName}}\",\r\n \t\t\t\"EventSource\": \"{{EventSource}}\",\r\n \t\t\t\"EventTime\": \"{{EventTime}}\",\r\n \t\t\t\"ReadOnly\": \"true\",\r\n \t\t\t\"Resources\": [\r\n \t\t\t],\r\n \t\t\t\"Username\": \"{{UserName}}\"\r\n \t\t}\r\n\t\t{{/each}}\r\n\t]\r\n\t{{#if (gte (indexOf (urlParam 'NextToken') 'true' 0) 0)}}\r\n\t {{#unless (includes (stringify (body)) 'NextToken')}}\r\n\t\t ,\"NextToken\": \"{{ faker 'random.alphaNumeric' 64 casing='upper' }}\"\r\n\t\t{{/unless}}\r\n\t{{/if}}\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "c5kh", + "sendFileAsBody": false, + "rules": [], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true + } + ], + "enabled": true, + "responseMode": null + } + ], + "rootChildren": [ + { + "type": "route", + "uuid": "b5e25f3a-a8e3-4128-9e45-f2654c5a599d" + }, + { + "type": "route", + "uuid": "77f82f1c-b06e-478a-8366-ab325830f00e" + } + ], + "proxyMode": false, + "proxyHost": "", + "proxyRemovePrefix": false, + "tlsOptions": { + "enabled": false, + "type": "CERT", + "pfxPath": "", + "certPath": "", + "keyPath": "", + "caPath": "", + "passphrase": "" + }, + "cors": true, + "headers": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "proxyReqHeaders": [ + { + "key": "", + "value": "" + } + ], + "proxyResHeaders": [ + { + "key": "", + "value": "" + } + ], + "data": [ + { + "uuid": "76dec2a5-ff63-4e81-9611-94b900ab16e1", + "id": "c5kh", + "name": "EventsData", + "documentation": "", + "value": "[\n {{#each (dataRaw 'EventsTypeData')}}\n {{#if (gte @isEvent 1)}}\n ,\n {{/if}}\n {{setVar 'isEvent' (add (urlParam name) @isEvent)}}\n {{#repeat (urlParam name comma=true)}}\n {\n \"AccessKeyId\": \"{{ faker 'random.alphaNumeric' 20 casing='upper' }}\",\n \"AccountId\": \"{{ faker 'random.numeric' 12 }}\",\n \"Error\": {{error}},\n {{#if error}}\n \"ErrorCode\": \"{{errorCode}}\",\n\t \"ErrorMessage\": \"{{errorMessage}}\",\n {{/if}}\n \"EventId\": \"{{ faker 'datatype.uuid' }}\",\n \"EventName\": \"{{oneOf (array 'LookupEvents' 'ListInstanceAssociations' 'AssumeRoleWithWebIdentity')}}\",\n \"EventSource\": \"{{oneOf (array 'cloudtrail.amazonaws.com' 'ssm.amazonaws.com' 'sts.amazonaws.com')}}\",\n \"EventTime\": \"{{ faker 'date.recent' }}\",\n \"EventType\": \"{{name}}\",\n \"PrincipalId\": \"{{ faker 'random.alphaNumeric' 20 casing='upper' }}\",\n \"UserName\": \"{{ faker 'internet.userName' }}\",\n \"UserRole\": \"{{ faker 'name.jobType' }}\"\n }\n {{/repeat}}\n {{/each}}\n]" + }, + { + "uuid": "5dce6340-bade-4336-8041-50fd22570055", + "id": "nu28", + "name": "EventsTypeData", + "documentation": "", + "value": "[\n {\n \"name\": \"AwsApiCall\",\n \"error\": false\n },\n {\n \"name\": \"AwsServiceEvent\",\n \"error\": false\n },\n {\n \"name\": \"AwsConsoleAction\",\n \"error\": true,\n \t\"errorCode\": \"ThrottlingException\",\n \t\"errorMessage\": \"Rate exceeded error\"\n },\n {\n \"name\": \"AwsConsoleSignIn\",\n \"error\": true,\n \"errorCode\": \"LoginErrorException\",\n \"errorMessage\": \"Login error\"\n }\n]" + } + ] +} \ No newline at end of file From 9e8ed5960df5c507feabc4d2f8b417443d06fc72 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Wed, 7 Jun 2023 15:52:15 +0200 Subject: [PATCH 447/447] enh(ci): do not stop delivery when one job fails (#4455) --- .github/workflows/plugin-delivery.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/plugin-delivery.yml b/.github/workflows/plugin-delivery.yml index d0a0226d7..56958e9bb 100644 --- a/.github/workflows/plugin-delivery.yml +++ b/.github/workflows/plugin-delivery.yml @@ -64,6 +64,7 @@ jobs: deliver-rpm: runs-on: [self-hosted, common] strategy: + fail-fast: false matrix: distrib: [el7, el8, el9] @@ -83,6 +84,7 @@ jobs: deliver-rpm-legacy: runs-on: [self-hosted, common] strategy: + fail-fast: false matrix: distrib: [el7, el8] major_version: ["21.10", "22.04", "22.10"] @@ -107,6 +109,7 @@ jobs: deliver-deb: runs-on: [self-hosted, common] strategy: + fail-fast: false matrix: distrib: [bullseye] @@ -125,6 +128,7 @@ jobs: deliver-deb-legacy: runs-on: [self-hosted, common] strategy: + fail-fast: false matrix: distrib: [bullseye] major_version: ["22.04", "22.10"]